基于id数组有效地循环对象

时间:2018-01-11 15:07:55

标签: javascript arrays object

我正在获取用户导航"州"在移动导航中作为数组。例如:

['3124', '5312', '5232']

我需要使用该状态,以获取ID为'5232'的对象,在对象中降低3级。

数组长度可能不同,这意味着它可以返回1到5个ID,因此我不必总是一直循环。

这就是导航数据的样子,使用与上面示例中使用的ID相同的ID,我希望我的函数返回"晚上" ID为'5232'的对象:

[
    { 
        id: "3124", 
        name: "women", 
        children: [
            {
                id: "5312",
                name: "dresses",
                children: [
                    {
                        id: "8399",
                        name: "wedding",
                        children: []
                    },
                    {
                        id: "5232",
                        name: "evening",
                        children: []
                    }
                ]
            },
            {
                id: "3291",
                name: "shoes",
                children: []
            }
        ] 
    },
    { 
        id: "9482", 
        name: "men", 
        children: [
            {
                id: "8292",
                name: "jackets",
                children: []
            },
            {
                id: "3829",
                name: "hats",
                children: []
            }
        ] 
    }
]

我和几位同事一直在谈论这个问题,但我们无法找到一种有效的方法。我们无法更改数据,但如果错误,我们可能会更改用户状态的保存方式。

我真的可以使用一些输入和想法来解决这个问题。

4 个答案:

答案 0 :(得分:0)

如果只关注效率,您可以尝试实现基本的嵌套for循环。我选择了变量名breadcrumb,因为这个概念与its role in site navigation类似。

function getState(breadcrumb, state) {
  let states = state;

  for (let id of breadcrumb) {
    for (state of states) {
      // found -- continue to next level
      if (state.id === id) {
        states = state.children;
        break;
      }
    }

    // not found
    if (state.id !== id) {
      return null;
    }
  }

  return state;
}

let state = [{ id: "3124", name: "women", children: [{ id: "5312", name: "dresses", children: [{ id: "8399", name: "wedding", children: [] }, { id: "5232", name: "evening", children: [] }] }, { id: "3291", name: "shoes", children: [] }] }, { id: "9482", name: "men", children: [{ id: "8292", name: "jackets", children: [] }, { id: "3829", name: "hats", children: [] }] }];
let breadcrumb = ['3124', '5312', '5232'];

console.log(getState(breadcrumb, state));

但是,如果您更关心代码可维护性,我建议采用更规范的方法:

function getState(breadcrumb, state) {
  return breadcrumb.reduce((state, id) => {
    return state !== null
      ? state.children.find(state => state.id === id)
      : state;
  }, { children: state });
}

let state = [{ id: "3124", name: "women", children: [{ id: "5312", name: "dresses", children: [{ id: "8399", name: "wedding", children: [] }, { id: "5232", name: "evening", children: [] }] }, { id: "3291", name: "shoes", children: [] }] }, { id: "9482", name: "men", children: [{ id: "8292", name: "jackets", children: [] }, { id: "3829", name: "hats", children: [] }] }];
let breadcrumb = ['3124', '5312', '5232'];

console.log(getState(breadcrumb, state));

答案 1 :(得分:0)

通过树中的路径查找节点的简单功能



function findNodeByPath(nodes, path) {
  let node;
  
  if (!path) return;

  for (let id of path) {
    if (!nodes) break;

    for (let child of nodes) {
      if (child.id === id) {
        node = child;
        nodes = node.children;
        break;
      }
    }  
  }

  return node;
}

let nodes = [
    { 
        id: "3124", 
        name: "women", 
        children: [
            {
                id: "5312",
                name: "dresses",
                children: [
                    {
                        id: "8399",
                        name: "wedding",
                        children: []
                    },
                    {
                        id: "5232",
                        name: "evening",
                        children: []
                    }
                ]
            },
            {
                id: "3291",
                name: "shoes",
                children: []
            }
        ] 
    },
    { 
        id: "9482", 
        name: "men", 
        children: [
            {
                id: "8292",
                name: "jackets",
                children: []
            },
            {
                id: "3829",
                name: "hats",
                children: []
            }
        ] 
    }
];

console.log(findNodeByPath(nodes, ['3124', '5312', '5232']));




答案 2 :(得分:0)

您可以迭代数组并仅获取给定路径ID的节点。



function getObject(tree, path) {
    var temp = { children: tree };
    return path.every(p => temp = temp.children.find(({ id }) => p === id))
        ? temp
        : undefined;
}

var data = [{ id: "3124", name: "women", children: [{ id: "5312", name: "dresses", children: [{ id: "8399", name: "wedding", children: [] }, { id: "5232", name: "evening", children: [] }] }, { id: "3291", name: "shoes", children: [] }] }, { id: "9482", name: "men", children: [{ id: "8292", name: "jackets", children: [] }, { id: "3829", name: "hats", children: [] }] }],
    path = ['3124', '5312', '5232'],
    result = getObject(data, path);

console.log(result);




答案 3 :(得分:0)

尝试使用递归函数

   function findById(id) {
      var founded = {};

      function recurse(data){
        for(var i = 0; i < data.length; i++) {
          if (data[i].id === id) {
            founded = data[i];
          } else if (data[i].children && data[i].children.length) {
            recurse(data[i].children);
          }
        }
      }

      recurse(catalog);
      return founded;
    };

一些演示:Demo