JavaScript 在多维数组或数组对象嵌套的数据结构中查找一个值

新手上路,请多包涵

函数

/**
 * 在数组中查找指定的项 ,支持多维数组 ,数组对象嵌套
 *
 * @param needle 要查找的值
 * @param haystack 被查找的数组
 * @param property 当被查找项是对象时( 数组对象嵌套 )这个参数作为要查找的值的属性名称 ,如果是多维数组不会有任何影响
 * @param children 当被查找项是对象时( 数组对象嵌套 )这个参数作为子集合属性名称 ,如果是多维数组不会有任何影响
 * @return undefined | Object | *
 */
function array_search(needle, haystack, property = 'id', children = 'children', result = { search: undefined }) {
    
    result.search = haystack.find((value, index, arr) => {
        return property === '' ? value == needle : value[property] == needle
    })

    let child;

    if (result.search === undefined) {
        haystack.forEach((value, index, arr) => {
            child = Array.isArray(value) ? value : value[children]
            if (child.length >= 0 && result.search === undefined) {
                array_search(needle, child, property, result)
            }
        })
    }

    return result.search
}

数据结构

$arr = [
    {
        id: 1,
        name: '一级菜单1',
        children: [
            { id: 2, name: '二级菜单1', children: [] },
            { id: 3, name: '二级菜单2', children: [] },
            { id: 4, name: '二级菜单3', children: [] },
        ]
    },
    {
        id: 5,
        name: '二级菜单1',
        children: [
            { id: 6, name: '二级菜单4', children: [] },
            { id: 7, name: '二级菜单5', children: [] },
            { id: 8, name: '二级菜单6', children: [] },
        ]
    }
];

想问下有没有更简单的方法 ,或优化的建议

阅读 10.2k
2 个回答

进一步优化一下, 返回值path为路径数组,若没有找到,则返回null

let haystack = [
  {
    id: "first",
    type: "list",
    children: [
      {
        id: "second0",
        type: "list",
        children: [
          {
            id: "third0",
            type: "list"
          },
          {
            id: "third1",
            type: "list"
          }
        ]
      },
      {
        id: "second1",
        type: "list"
      }
    ]
  },
  {
    id: "first1",
    type: "list",
    children: [
      {
        id: "second2",
        type: "list"
      }
    ]
  }
];

function array_search(
  haystack,
  needle,
  path = [],
  property = "id",
  children = "children"
) {
  if (
    haystack.some(item => {
      if (item[property] === needle) {
        path.push(item[property]);
        return true;
      } else if (item[children]) {
        path.push(item[property]);
        if (array_search(item[children], needle, path)) {
          return true;
        } else {
          path = [];
          return false;
        }
      } else {
        return false;
      }
    })
  ) {
    return path;
  } else {
    return null;
  }
}

let res = array_search(haystack, "third1");

console.log(res); // ["first", "second0", "third1"]
/**
 * 嵌套查找
 * @param obj 目标对象或数组
 * @param keyChain 要查找的目标值的 key 链
 */
function nestedSearch(obj, keyChain) {
  const keys = keyChain.split(".");
  return keys.reduce((p, n) => {
    p = p?.[n];
    return p;
  }, obj)
}
// 例如你的示例数据:
nestedSearch($arr, "0.children.0.id"); // 2
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏