对象中的多维数组

时间:2016-12-14 20:31:23

标签: javascript arrays object

请浏览此javascript对象:

var obj = [{
  id: "A",
  children: [{
    id: "B",
    children: [{
      id: "C",
      children: [{
        id: "D",
        children: [{
          id: "E",
          children: [{
            id: "F"
          }]
        }]
      }, {
        id: "G",
        children: {
          id: "H"
        }
      }]
    }, {
      id: "I"
    }]
  }, {
    id: "J",
    children: [{
      id: "K"
    }]
  }]
}, {
  id: "L"
}, {
  id: "M",
  children: {
    id: "N",
    children: [{
      id: "O"
    }]
  }
}, {
  id: "P"
}];

如何编写JavaScript代码以递归方式解析它并在控制台中打印所有ID,以便输出如下所示:

A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P

这是我能达到的目标。在那之后我无法想到任何逻辑。

for ( i=0 ; i < obj.length ; i++ ){
         var objId = obj[i];
         for( j=i; j<1 ; j++){
             console.log(obj[j].id);
             console.log(obj[j].children[j].id);
         }
     }

我不明白应该在这里应用什么逻辑。帮忙。

3 个答案:

答案 0 :(得分:5)

您可以使用depth-first search算法的迭代和递归方法。

编辑:为儿童扩展为对象。

&#13;
&#13;
var data = [{ id: "A", children: [{ id: "B", children: [{ id: "C", children: [{ id: "D", children: [{ id: "E", children: [{ id: "F" }] }] }, { id: "G", children: { id: "H" } }] }, { id: "I" }] }, { id: "J", children: [{ id: "K" }] }] }, { id: "L" }, { id: "M", children: { id: "N", children: [{ id: "O" }] } }, { id: "P" }];

data.forEach(function iter(a) {
    console.log(a.id);
    if (Array.isArray(a.children)) {
        a.children.forEach(iter);
        return;
    }
    if (a.children && typeof a.children === 'object') { // omit this part
        iter(a.children);                               // if children is
    }                                                   // always an array
});
&#13;
&#13;
&#13;

此版本收集所有必要的数据并将其以数组形式返回。

&#13;
&#13;
var data = [{ id: "A", children: [{ id: "B", children: [{ id: "C", children: [{ id: "D", children: [{ id: "E", children: [{ id: "F" }] }] }, { id: "G", children: { id: "H" } }] }, { id: "I" }] }, { id: "J", children: [{ id: "K" }] }] }, { id: "L" }, { id: "M", children: { id: "N", children: [{ id: "O" }] } }, { id: "P" }],
    result = data.reduce(function iter(r, o) {
        r.push(o.id);
        if (Array.isArray(o.children)) {
            return o.children.reduce(iter, r);
        }
        if (o.children && typeof o.children === 'object') { // omit this part
            return iter(r, o.children);                     // if children is
        }                                                   // always an array
        return r;
    }, []);

console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以使用以下ES6功能。请注意,在两个地方您没有将children定义为数组,我认为这是一个错误。如果它是缩进的,我强烈建议重新考虑,并使其始终保持一致。

function getIds(data) {
    return data.reduce((acc, el) => acc.concat(el.id, getIds(el.children || [])), [])
}

var obj = [{
  id: "A",
  children: [{
    id: "B",
    children: [{
      id: "C",
      children: [{
        id: "D",
        children: [{
          id: "E",
          children: [{
            id: "F"
          }]
        }]
      }, {
        id: "G",
        children: [{
          id: "H"
        }]
      }]
    }, {
      id: "I"
    }]
  }, {
    id: "J",
    children: [{
      id: "K"
    }]
  }]
}, {
  id: "L"
}, {
  id: "M",
  children: [{
    id: "N",
    children: [{
      id: "O"
    }]
  }]
}, {
  id: "P"
}];

console.log(getIds(obj).join('\n'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

你所展示的内容看起来像是要求深度优先解决方案,因为id的顺序清楚地按字母顺序排列,并且首先按深度排序然后按顺序排序。

结果,将收集遇到的每个id,然后检查更深的id。这可以,也可能应该通过递归完成。

这是一个例子。

&#13;
&#13;
  
var obj=[{id:"A",children:[{id:"B",children:[{id:"C",children:[{id:"D",children:[{id:"E",children:[{id:"F"}]}]},{id:"G",children:{id:"H"}}]},{id:"I"}]},{id:"J",children:[{id:"K"}]}]},{id:"L"},{id:"M",children:{id:"N",children:[{id:"O"}]}},{id:"P"}];

var ids = [];//output holder
(function tree(cur){ //recursive function
 for(var i = 0; i < cur.length; i++){ //iterate current set
     ids.push(cur[i].id); //always store id
     if(cur[i].children) tree(cur[i].children); //recurse if children exist
 }
})(obj) //start from the top
    
console.log(ids);
&#13;
&#13;
&#13;