繁体   English   中英

如何在JS中使用递归查找嵌套数组中的对象

[英]How to find a object in a nested array using recursion in JS

考虑以下深度嵌套的数组:

const array = [
    {
        id: 1,
        name: "bla",
        children: [
            {
                id: 23,
                name: "bla",
                children: [{ id: 88, name: "bla" }, { id: 99, name: "bla" }]
            },
            { id: 43, name: "bla" },
            {
                id: 45,
                name: "bla",
                children: [{ id: 43, name: "bla" }, { id: 46, name: "bla" }]
            }
        ]
    },
    {
        id: 12,
        name: "bla",
        children: [
            {
                id: 232,
                name: "bla",
                children: [{ id: 848, name: "bla" }, { id: 959, name: "bla" }]
            },
            { id: 433, name: "bla" },
            {
                id: 445,
                name: "bla",
                children: [
                    { id: 443, name: "bla" },
                    {
                        id: 456,
                        name: "bla",
                        children: [
                            {
                                id: 97,
                                name: "bla"
                            },
                            {
                                id: 56,
                                name: "bla"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        id: 15,
        name: "bla",
        children: [
            {
                id: 263,
                name: "bla",
                children: [{ id: 868, name: "bla" }, { id: 979, name: "bla" }]
            },
            { id: 483, name: "bla" },
            {
                id: 445,
                name: "bla",
                children: [{ id: 423, name: "bla" }, { id: 436, name: "bla" }]
            }
        ]
    }
];

我将如何使用递归通过键获取可能深度嵌套的某个对象? 我已经尝试过这个,但这不适用于嵌套深于 2 层的情况,然后它只返回undefined

const findItemNested = (arr, itemId, nestingKey) => {
    for (const i of arr) {
        console.log(i.id);
        if (i.id === itemId) {
            return i;
        }
        if (i[nestingKey]) {
            findItemNested(i[nestingKey], itemId, nestingKey);
        }
    }
};

结果应该是:

const res = findItemNested(array, 959, "children"); >> { id: 959, name: "bla" }

这也许也可以使用.find来实现,或者只是为了展平数组(通过 children 键),但使用递归对我来说似乎是最合乎逻辑的解决方案。 有没有人有解决方案?

提前致谢 :)。

您可以使用递归reduce

 const array=[{id:1,name:"bla",children:[{id:23,name:"bla",children:[{id:88,name:"bla"},{id:99,name:"bla"}]},{id:43,name:"bla"},{id:45,name:"bla",children:[{id:43,name:"bla"},{id:46,name:"bla"}]}]},{id:12,name:"bla",children:[{id:232,name:"bla",children:[{id:848,name:"bla"},{id:959,name:"bla"}]},{id:433,name:"bla"},{id:445,name:"bla",children:[{id:443,name:"bla"},{id:456,name:"bla",children:[{id:97,name:"bla"},{id:56,name:"bla"}]}]}]},{id:15,name:"bla",children:[{id:263,name:"bla",children:[{id:868,name:"bla"},{id:979,name:"bla"}]},{id:483,name:"bla"},{id:445,name:"bla",children:[{id:423,name:"bla"},{id:436,name:"bla"}]}]}]; const findItemNested = (arr, itemId, nestingKey) => ( arr.reduce((a, item) => { if (a) return a; if (item.id === itemId) return item; if (item[nestingKey]) return findItemNested(item[nestingKey], itemId, nestingKey) }, null) ); const res = findItemNested(array, 959, "children"); console.log(res);

您也可以使用递归与Array.find如下所示

 const array=[{id:1,name:"bla",children:[{id:23,name:"bla",children:[{id:88,name:"bla"},{id:99,name:"bla"}]},{id:43,name:"bla"},{id:45,name:"bla",children:[{id:43,name:"bla"},{id:46,name:"bla"}]}]},{id:12,name:"bla",children:[{id:232,name:"bla",children:[{id:848,name:"bla"},{id:959,name:"bla"}]},{id:433,name:"bla"},{id:445,name:"bla",children:[{id:443,name:"bla"},{id:456,name:"bla",children:[{id:97,name:"bla"},{id:56,name:"bla"}]}]}]},{id:15,name:"bla",children:[{id:263,name:"bla",children:[{id:868,name:"bla"},{id:979,name:"bla"}]},{id:483,name:"bla"},{id:445,name:"bla",children:[{id:423,name:"bla"},{id:436,name:"bla"}]}]}]; function findById(arr, id, nestingKey) { // if empty array then return if(arr.length == 0) return // return element if found else collect all children(or other nestedKey) array and run this function return arr.find(d => d.id == id) || findById(arr.flatMap(d => d[nestingKey] || []), id) || 'Not found' } console.log(findById(array, 12, 'children')) console.log(findById(array, 483, 'children')) console.log(findById(array, 1200, 'children'))

这应该有效:

function findByIdRecursive(array, id) {
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    if (element.id === id) {
      return element;
    } else {
      if (element.children) {
        const found = findByIdRecursive(element.children, id);

        if (found) {
          return found;
        }
      }
    }
  }
}

我们在大部分数据处理中使用对象扫描 它对各种事情都很棒,但确实需要一段时间才能让您满意。 可以这样回答你的问题:

 // const objectScan = require('object-scan'); const find = (data, id) => objectScan(['**(^children$).id'], { abort: true, rtn: 'parent', useArraySelector: false, filterFn: ({ value }) => value === id })(data); const array=[{id:1,name:"bla",children:[{id:23,name:"bla",children:[{id:88,name:"bla"},{id:99,name:"bla"}]},{id:43,name:"bla"},{id:45,name:"bla",children:[{id:43,name:"bla"},{id:46,name:"bla"}]}]},{id:12,name:"bla",children:[{id:232,name:"bla",children:[{id:848,name:"bla"},{id:959,name:"bla"}]},{id:433,name:"bla"},{id:445,name:"bla",children:[{id:443,name:"bla"},{id:456,name:"bla",children:[{id:97,name:"bla"},{id:56,name:"bla"}]}]}]},{id:15,name:"bla",children:[{id:263,name:"bla",children:[{id:868,name:"bla"},{id:979,name:"bla"}]},{id:483,name:"bla"},{id:445,name:"bla",children:[{id:423,name:"bla"},{id:436,name:"bla"}]}]}]; console.log(find(array, 12)); // => { id: 12, name: 'bla', children: [ { id: 232, name: 'bla', children: [ { id: 848, name: 'bla' }, { id: 959, name: 'bla' } ] }, { id: 433, name: 'bla' }, { id: 445, name: 'bla', children: [ { id: 443, name: 'bla' }, { id: 456, name: 'bla', children: [ { id: 97, name: 'bla' }, { id: 56, name: 'bla' } ] } ] } ] } console.log(find(array, 483)); // => { id: 483, name: 'bla' } console.log(find(array, 959)); // => { id: 959, name: 'bla' } console.log(find(array, 1200)); // => undefined
 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script src="https://bundle.run/object-scan@13.7.1"></script>

免责声明:我是对象扫描的作者

你可以做:

 const array=[{id:1,name:"bla",children:[{id:23,name:"bla",children:[{id:88,name:"bla"},{id:99,name:"bla"}]},{id:43,name:"bla"},{id:45,name:"bla",children:[{id:43,name:"bla"},{id:46,name:"bla"}]}]},{id:12,name:"bla",children:[{id:232,name:"bla",children:[{id:848,name:"bla"},{id:959,name:"bla"}]},{id:433,name:"bla"},{id:445,name:"bla",children:[{id:443,name:"bla"},{id:456,name:"bla",children:[{id:97,name:"bla"},{id:56,name:"bla"}]}]}]},{id:15,name:"bla",children:[{id:263,name:"bla",children:[{id:868,name:"bla"},{id:979,name:"bla"}]},{id:483,name:"bla"},{id:445,name:"bla",children:[{id:423,name:"bla"},{id:436,name:"bla"}]}]}]; const findItemNested = (arr, itemId, nestingKey) => arr.reduce((a, c) => { return a.length ? a : c.id === itemId ? a.concat(c) : c[nestingKey] ? a.concat(findItemNested(c[nestingKey], itemId, nestingKey)) : a }, []); const res = findItemNested(array, 959, "children"); if (res.length) { console.log(res[0]); }

这将使用逐级递归查找,它将尝试在数组中查找项目,然后使用数组中每个项目的子项调用自身:

新的浏览器会有 Array.prototype.flatten 但在这种情况下我已经单独添加了 flatten 功能。

 const array = [{"id":1,"name":"bla","children":[{"id":23,"name":"bla","children":[{"id":88,"name":"bla"},{"id":99,"name":"bla"}]},{"id":43,"name":"bla"},{"id":45,"name":"bla","children":[{"id":43,"name":"bla"},{"id":46,"name":"bla"}]}]},{"id":12,"name":"bla","children":[{"id":232,"name":"bla","children":[{"id":848,"name":"bla"},{"id":959,"name":"bla"}]},{"id":433,"name":"bla"},{"id":445,"name":"bla","children":[{"id":443,"name":"bla"},{"id":456,"name":"bla","children":[{"id":97,"name":"bla"},{"id":56,"name":"bla"}]}]}]},{"id":15,"name":"bla","children":[{"id":263,"name":"bla","children":[{"id":868,"name":"bla"},{"id":979,"name":"bla"}]},{"id":483,"name":"bla"},{"id":445,"name":"bla","children":[{"id":423,"name":"bla"},{"id":436,"name":"bla"}]}]}]; const flatten = (arr) => arr.reduce((result, item) => result.concat(item), []); const findBy = (findFunction, subItemsKey) => (array) => //array is empty (can be when children of children of children does not exist) array.length === 0 ? undefined //return undefined when array is empty : array.find(findFunction) || //return item if found findBy(findFunction, subItemsKey)(//call itself when item is not found flatten( //take children from each item and flatten it //([[child],[child,child]])=>[child,child,child] array.map((item) => item[subItemsKey] || []), ), ); const findChildrenById = (array) => (value) => findBy((item) => item.id === value, 'children')(array); const findInArray = findChildrenById(array); console.log('found', findInArray(99)); console.log('not found', findInArray({}));

您需要遍历对象,然后需要使用递归解析每个对象。 试试这里提到的答案: JavaScript recursive search in JSON object

代码:

`function findNode(id, currentNode) { var i, currentChild, result;

if (id == currentNode.id) {
    return currentNode;
} else {

    // Use a for loop instead of forEach to avoid nested functions
    // Otherwise "return" will not work properly
    for (i = 0; i < currentNode.children.length; i += 1) {
        currentChild = currentNode.children[i];

        // Search in the current child
        result = findNode(id, currentChild);

        // Return the result if the node has been found
        if (result !== false) {
            return result;
        }
    }

    // The node has not been found and we have no more options
    return false;
}

}`

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM