根据对象名称合并嵌套的对象数组

时间:2018-04-03 16:38:35

标签: javascript

所以我有这样的数组:

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);
    }
}

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

我不知道你想要实现什么,但在我看来你应该使用对象。

欢迎

答案 1 :(得分: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循环可能是您的最佳选择。

话虽如此,尽管我们在评论中进行了讨论,但我仍然不能完全清楚你想要实现的目标。因此,我决定编写一个通用的合并函数。此函数可以合并任何类型的对象。 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,否则{1}}总是获胜。

undefined
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%;
}

1 在使用此功能之前,我留给您证明算法的正确性:-P