操纵对象,使其自身的属性填充对象本身内的数组

时间:2016-07-22 09:26:45

标签: javascript arrays javascript-objects

我有一个像这样的对象数组:

var array = [{
code : "1",
name : "code1",
parentCode : "0",
children : []
},{
code : "0",
name : "code0",
parentCode : "#",
children : []
}]

如何推送父母的children数组,孩子们的代码?理想情况下,推送后,array[1].children应为["1"]

我试过了:

for (var i = 0; i<array.length;i++) {
    var parentArray = array.find(function(a){
         return a.parentCode == array[i].parentCode 
         });
parentArray.children.push(array[i].code);
}

结果是混乱的。 children数组包含无意义的条目的总混合(最初不属于那里的条目,因为它们的父级不同)

我应该采用不同的方式吗?

以下是我想要完成的前/后的示例:

BEFORE:

var array = [{
code : "0",
name : "code0",
parentCode : "#",
children : []
},{
code : "1",
name : "code1",
parentCode : "0",
children : []
},{
code : "2",
name : "code2",
parentCode : "0",
children : []
},{
code : "3",
name : "code3",
parentCode : "0",
children : []
},{
code : "4",
name : "code4",
parentCode : "1",
children : []
},{
code : "5",
name : "code5",
parentCode : "1",
children : []
}]

之后(期望的结果):

 var array = [{
code : "0",
name : "code0",
parentCode : "#",
children : ["1","2","3"]
},{
code : "1",
name : "code1",
parentCode : "0",
children : ["4","5"]
},{
code : "2",
name : "code2",
parentCode : "0",
children : []
},{
code : "3",
name : "code3",
parentCode : "0",
children : []
},{
code : "4",
name : "code4",
parentCode : "1",
children : []
},{
code : "5",
name : "code5",
parentCode : "1",
children : []
}]

1 个答案:

答案 0 :(得分:2)

我可能会在两次通过中做到这一点(但见下文):

  1. 找到所有父母,并按代码

  2. 构建对他们的引用地图
  3. 找到所有孩子,将他们推到父母身上

  4. 这样的事情:

    &#13;
    &#13;
    // The data
    var array = [{ code : "0", name : "code0", parentCode : "#", children : [] },{ code : "1", name : "code1", parentCode : "0", children : [] },{ code : "2", name : "code2", parentCode : "0", children : [] },{ code : "3", name : "code3", parentCode : "0", children : [] },{ code : "4", name : "code4", parentCode : "1", children : [] },{ code : "5", name : "code5", parentCode : "1", children : [] }];
    
    // Build a mapping object of parents keyed by their codes
    var map = Object.create(null);
    array.forEach(function(entry) {
      map[entry.code] = entry;
    });
    
    // Push child codes into the parent `children` arrays
    array.forEach(function(entry) {
      if (entry.parentCode != "#") {
        var parent = map[entry.parentCode];
        if (parent) {
          parent.children.push(entry.code);
        }
      }
    });
    
    // Show result
    console.log(array);
    &#13;
    &#13;
    &#13;

    两次通过的原因是避免通过array进行不必要的搜索,寻找每个父母。查找&#34;映射&#34;中的条目对象比在数组中查找条目更有效。

    但是如果你想一次性完成,你的find方法也会起作用。您尝试的问题是,您要将parentCodeparentCode进行比较(您应该将孩子parentCode与孩子{{1}进行比较你没有找到父母(也许你肯定知道他们会永远存在):

    &#13;
    &#13;
    code
    &#13;
    &#13;
    &#13;

    只是为了好玩,这里是ES2015 +中的映射版本(不会在没有转换的情况下使用旧浏览器):

    &#13;
    &#13;
    // The data
    var array = [{ code : "0", name : "code0", parentCode : "#", children : [] },{ code : "1", name : "code1", parentCode : "0", children : [] },{ code : "2", name : "code2", parentCode : "0", children : [] },{ code : "3", name : "code3", parentCode : "0", children : [] },{ code : "4", name : "code4", parentCode : "1", children : [] },{ code : "5", name : "code5", parentCode : "1", children : [] }];
    
    // Doing it in a single loop (but note that Array#find
    // is also a loop, so this is less efficient than using
    // a mapping object
    array.forEach(function(child) {
      var parent = array.find(function(p) {
        return p.code == child.parentCode;
      });
      if (parent) {
        parent.children.push(child.code);
      }
    });
    
    // Show result
    console.log(array);
    &#13;
    &#13;
    &#13;

    如果你真的想要模糊,你可以(ab)使用// The data let array = [{ code : "0", name : "code0", parentCode : "#", children : [] },{ code : "1", name : "code1", parentCode : "0", children : [] },{ code : "2", name : "code2", parentCode : "0", children : [] },{ code : "3", name : "code3", parentCode : "0", children : [] },{ code : "4", name : "code4", parentCode : "1", children : [] },{ code : "5", name : "code5", parentCode : "1", children : [] }]; // Build a mapping object of parents keyed by their codes let map = new Map(); array.forEach(entry => { map.set(entry.code, entry); }); // Push child codes into the parent `children` arrays array.forEach(entry => { if (entry.parentCode != "#") { let parent = map.get(entry.parentCode); if (parent) { parent.children.push(entry.code); } } }); // Show result console.log(array);来构建映射对象:

    Array#reduce