【问题标题】:Merge nested arrays of objects base on the name of objects根据对象的名称合并嵌套的对象数组
【发布时间】:2018-09-13 01:50:28
【问题描述】:

所以我有这样的数组数组:

array1 = [boot = [value = [ enable =["some string"]]]]

还有一个对象数组:

array2 = [options=[ enable=[]], boot =[value =[something =[]]]]

我需要使用名称的“路径”将 array1 合并到 array2 以便我得到:

output = [options=[ enable=[]], boot =[value =[something[], enable =["some string"]]]

所以我必须深入研究对象,检测对象的通用名称,然后将 array1 的其余部分推到 array2 中的正确位置。知道怎么做吗?我尝试了一个递归函数,但它没有给我预期的结果! 这是我写的函数:

function mergeArrays(menu, array){
  const arrayItem = Object.keys(array)[0];
  var index = -1;
  Object.values(menu).map(menuItem =>{
    if(Object.keys(menuItem).indexOf(arrayItem) !== -1){
      index = Object.keys(menuItem).indexOf(arrayItem);
    }
  })
  if(index === -1){
    menu.push(array);
    return menu;
  }else{
      const menuItem = Object.values(menu)[index];
      const rest = Object.values(menuItem);
      const arrayItem = Object.values(array)[0];
      mergeArrays(rest, arrayItem);
    }
}

【问题讨论】:

  • 这些都是数组,不是对象
  • 您在第二个数组中忘记了 ]。

标签: javascript


【解决方案1】:

请注意,a = [ v = 1 ] 是一个数组,而不是一个对象。它与v = 1; a = [ v ] 相同,归结为a = [ 1 ],如果要读取第一个值,则必须写入a[0]。但是,由于您的合并策略是“基于对象的名称”,因此使用字典 d = { v : 1 } 似乎更合适。在这种情况下,您可以使用 d["v"] 通过名称获取值。

在 JavaScript 世界中,人们使用“对象”这个词而不是“字典”。不管是什么词,你需要记住的是对象和数组是不同的,因为它们继承自不同的类。实际上,{} 表示new Object(),而[] 表示new Array()。此外,大多数时候人们使用for ... in 循环枚举对象的属性,并使用for ... of 循环或for 循环遍历数组的元素。同样,知道您对对象的名称感兴趣,for ... in 循环可能是您的最佳选择。

话虽如此,尽管我们在 cmets 中进行了讨论,但我仍然不完全清楚您要达到的目标。因此,我决定编写一个通用的合并函数。此函数能够合并任何类型的对象。1以下是几个用例:

> | merge("azerty", null) // b wins
< | null
> | merge("azerty", { t : true }) // b wins
< | { t : true }
> | merge({ t : true }, "azerty") // b wins
< | "azerty"
> | merge([1, 2, 3], [undefined, 5]) // a[0] wins, b[1] wins
< | [1, 5, 3]
> | merge("azerty", undefined) // a wins
< | "azerty"

合并策略非常简单,可以总结如下:

如果a 是一个数组并且b 是一个数组,或者如果a 是一个字典并且b 是一个字典,则递归合并它们,否则,b 总是获胜,除非它是@987654341 @。

main({
  m : [ 1, { ms : "ms", mf : false }, 3 ],
  n : { ns : "ns", na : [ null, undefined ] },
  o : { os : "os" }
}, {
  m : [ -1, { mt : true } ], 
  n : { nt : true, na : [ undefined, null ] }
});

function merge (a, b) {
  if (isFunction(b)) {
    return b;
  } else if (isArray(b)) {
    if (!isArray(a)) {
      return b;
    } else {
      var max = Math.max(
        a.length, b.length
      );
      for (var i = 0; i < max; i++) {
        b[i] = merge(a[i], b[i]);
      }
      return b;
    }
  } else if (isComplex(b)) {
    if (!isComplex(a) || isArray(a) || isFunction(a)) {
      return b;
    } else {
      for (var k in a) {
        b[k] = merge(a[k], b[k]);
      }
      return b;
    }
  } else if (b === undefined) {
    if (isFunction(a)) {
      return a;
    } else if (isArray(a)) {
      return merge(a, []);
    } else if (isComplex(a)) {
      return merge(a, {});
    } else {
      return a;
    }
  } else {
    return b;
  }
}

function main (a, b) {
  var pre = document.getElementsByTagName("pre");
  b = merge(a, b);
  pre[0].textContent = "a = " + (
    fixUndef(JSON.stringify(a, markUndef, 2))
  );
  pre[1].textContent = "b = " + (
    fixUndef(JSON.stringify(b, markUndef, 2))
  );
}

function isComplex (x) {
  return x === Object(x);
}

function isArray (x) {
  return x instanceof Array;
}

function isFunction (x) {
  return typeof x === "function";
}

// JSON.stringify() replaces
// `undefined` with `null`, the
// below functions are meant to
// fix this behavior.

function markUndef (k, v) {
  return v === undefined ? "UNDEF" : v;
}

function fixUndef (s) {
  return s.replace("\"UNDEF\"", "undefined");
}
pre {
  display : inline-block;
  vertical-align: top;
  width: 50%;
}
&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;

1 在使用这个函数之前,我把它留给你证明算法的正确性:-P

【讨论】:

    【解决方案2】:

    Javascript 不会像您期望的那样执行您的数组。即

    array1 = [boot = [value = [ enable =["some string"]]]]
    

    相同
    [[[["some string"]]]]
    

    因此,如果您尝试合并数组 1 和数组 2,您将得到:-

    [[[["some string"]]],[[]],[[[]]]]
    

    我不知道你想要达到什么目的,但我认为你应该使用 object 来代替。

    欢迎

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-11
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多