Javascript嵌套数组获取元素

时间:2017-04-21 20:32:11

标签: javascript jquery recursion

我有一个像:

这样的数组
"pages": [{
    "key": "1",
    "pages": [{
        "key": "2",
        "pages": [{
            "key": "3"
        }]
    },
        {
            "key": "4",
            "pages": [{
                "key": "5"
            }]

        }]
}]

其中键1和4处于同一级别,1包含2,其中包含3,键4包含5.我想要的结果是顺序[3,2,5,1,4]。我尝试了以下递归,但我无法获得正确的顺序。

 function fnGetAll (oTopDetailPage, array) {
    var i;

    for (i=0; i<oTopDetailPage.length; i++) {
        array.push(oTopDetailPage[i]);
        if(oTopDetailPage[i].pages) {
            fnGetAllSubPages(oTopDetailPage[i].pages, array);
        }
    }
    return array;
}

2 个答案:

答案 0 :(得分:5)

如果你想要一个Depth-first search,你可以先对孩子进行迭代,然后再取实际的密钥。

结果是一个数组,有点不同,然后是给定的数组。

function getDepthFirst(object) {
    var result = [];
    object.pages.forEach(function iter(a) {
        Array.isArray(a.pages) && a.pages.forEach(iter);
        result.push(a.key);
    });
    return result;
}

var data = { pages: [{ key: 1, pages: [{ key: 2, pages: [{ key: 3 }] }, { key: 4, pages: [{ key: 5 }] }] }] };
  
console.log(getDepthFirst(data)); // [3, 2, 5, 4, 1]

使用临时数组获取{{1>反向级别订单遍历结果[3, 5, 2, 4, 1]的附录,该数据收集来自同一级别的所有数据并返回包含所有级别项目的数组,从最高到最低。

回调在实际级别上使用闭包。

function getData(object) {
    var temp = [];
    object.pages.forEach(function iter(level) {
        return function (a) {
            Array.isArray(a.pages) && a.pages.forEach(iter(level + 1));
            temp[level] = temp[level] || [];
            temp[level].push(a.key);
        };
    }(0));
    return temp.reduceRight(function (r, a) {
        return r.concat(a);
    });
}

var data = { pages: [{ key: 1, pages: [{ key: 2, pages: [{ key: 3 }] }, { key: 4, pages: [{ key: 5 }] }] }] };

console.log(getData(data)); // [3, 5, 2, 4, 1]

答案 1 :(得分:1)

你的root容器有点奇怪,因为它的javascript无效。我假设它{pages: ... }并附上{},但即使这样也没有意义,因为根容器不包含key属性

您应首先修复节点,使其具有统一的构造,例如

type Node = Node { key: String, pages: [Node] }

然后实现深度优先搜索是微不足道的

&#13;
&#13;
const dfs = ({key, pages = []}) =>
  [...pages.reduce((acc, p) => acc.concat(dfs(p)), []), key]
  
const data = {
  "key": "1",
  "pages": [{
      "key": "2",
      "pages": [{
          "key": "3"
      }]
  },
  {
      "key": "4",
      "pages": [{
          "key": "5"
      }]
  }]
}
  
console.log(dfs(data))
// [ '3', '2', '5', '4', '1' ]
&#13;
&#13;
&#13;

如果您正在手动构建数据,请不要这样做。相反,我建议你制作一个简单的构造函数来统一构建数据。由于现在保证每个节点都具有keypages属性,因此我们可以删除pages = []dfs的默认参数值。这样做更好,因为我们可以避免任何可能试图适应缺失属性的防御性编程。

&#13;
&#13;
const dfs = ({key, pages}) =>
  [...pages.reduce((acc, p) => acc.concat(dfs(p)), []), key]
  

const makeNode = (key, ...pages) => ({key, pages})

const data =
  makeNode('1',
    makeNode('2',
      makeNode('3')),
    makeNode('4',
      makeNode('5')))
  
console.log(dfs(data))
// [ '3', '2', '5', '4', '1' ]
&#13;
&#13;
&#13;