首页 > 解决方案 > 将包含数组作为值的对象减少为单个数组

问题描述

问题:根据条件将包含数组作为值的对象减少为单个数组。详细信息:我有一个包含数组作为值的对象。

{
  514:["564"],
  812:["514"],
  1006:["921","812"],
  1012: ["1002"],
  1024:["6994","7992"],
  6923:["1024","1006"],
  6994:["1012","7182"],
  7992:["5921"],
}

我想编写一个javascript函数,可以根据我传递给函数的键将此对象简化为数组。结果数组应该有我们传递给函数的 id 和它在对象中的值以及与这些值相对应的任何其他值,直到我们找不到键为止。例如:如果我通过 6994,那么我需要函数的结果为以下数组

["6994", "1012", "7182", "1002"]

我尝试了以下工作。想知道是否有更好更有效的解决方案:

function getChildIds({ treeMap, id }) {
  let childIds = [id];
  let parentIds = [id];
  while(!!parentIds.length) {
    let tempIds = [];
    parentIds.forEach((parentId, index) => {
      if(!!treeMap[parentId]) {
        tempIds.push(...treeMap[parentId]);
        childIds.push(...treeMap[parentId]);
      }
    });
    parentIds = tempIds;
  }
  return childIds;
}

编辑:递归不是首选,因为这个对象可能非常大,并且浏览器堆栈内存不足是不可取的。

标签: javascriptecmascript-6

解决方案


您可以从给定节点获取嵌套节点。

类型:深度优先搜索:有序(LNR)

const
    getNodes = node => [node, ...(nodes[node] || []).flatMap(getNodes)],
    nodes = { 514: ["564"], 812: ["514"], 1006: ["921", "812"], 1012: ["1002"],  1024: ["6994", "7992"], 6923: ["1024", "1006"], 6994: ["1012", "7182"], 7992: ["5921"] },
    node = "6994",
    result = getNodes(node);

console.log(result);

另一种方法使用堆栈,它可能比上述递归reduce方法更快。

这种方法的顺序是不同的,因为树遍历是按级别顺序(广度优先搜索)。

const
    getNodes = node => {
        const
            stack = [node],
            result = [];

        while (stack.length) {
            const
                n = stack.shift();
            result.push(n);
            if (!nodes[n]) continue;
            stack.push(...nodes[n]);                   
        }
        return result; 
    },
    nodes = { 514: ["564"], 812: ["514"], 1006: ["921", "812"], 1012: ["1002"],  1024: ["6994", "7992"], 6923: ["1024", "1006"], 6994: ["1012", "7182"], 7992: ["5921"] },
    node = "6994",
    result = getNodes(node);

console.log(result);


推荐阅读