简体   繁体   中英

Find an object in an array of deeply nested objects recursively

I have an array, and each item is an object with unique Ids. Some items may also have children, and it can have children array inside a children array. I'm trying to pick an item using an Id.

           const array = [
                {
                    uuid: '40E75F3DE56B4B11B3AFBDE46785737B'
                }, {
                    uuid: '9CEF74766BBB4B9682B7817B43CEAE48'
                }, {
                    uuid: '34F209A883D3406FBA6BACD9E07DB1D9',
                    children: [{
                        uuid: 'F429C51BF01C405DA517616E0E16DE4E',
                        children: [{
                            uuid: '8823CFCE7D4645C68991332091C1A05C'
                        }, {
                            uuid: '58A9345E881F48C980498C7FFB68667D'
                        }]
                    }]
                }, {
                    uuid: '152488CC33434A8C9CACBC2E06A7E535'
                }, {
                    uuid: '9152B3DEF40F414BBBC68CACE2F5F6E4'
                }, {
                    uuid: 'B9A39766B17E4406864D785DB6893C3D'
                },
                {
                    uuid: '3J4H4J5HN6K4344D785DBJ345HSSODF',
                    children: [
                        {
                            uuid: 'EAB14DD72DA24BB88B4837C9D5276859'
                        },
                        {
                            uuid: 'FFA80D043380481F8835859A0839512B'
                        },
                        {
                            uuid: '9679687190354FA79EB9D1CA7B4962B1'
                        }
                    ]
                }
            ]

The code below works for a simple array without children. I need a function, or a lodash module that can recursively search the entire array and return the object(item in the array)

findContainingObject(array, uuid) {
    let result = [];
    result = array.filter( item => {
        return item.uuid === uuid
    })
    return result;
}

Expected Outputs:

findContainingObject(array, '40E75F3DE56B4B11B3AFBDE46785737B')

               {
                 uuid: '40E75F3DE56B4B11B3AFBDE46785737B'
               }

findContainingObject(array, '34F209A883D3406FBA6BACD9E07DB1D9')
                {
                    uuid: '34F209A883D3406FBA6BACD9E07DB1D9',
                    children: [{
                        uuid: 'F429C51BF01C405DA517616E0E16DE4E',
                        children: [{
                            uuid: '8823CFCE7D4645C68991332091C1A05C'
                        }, {
                            uuid: '58A9345E881F48C980498C7FFB68667D'
                        }]
                    }]
                }

findContainingObject(array, '58A9345E881F48C980498C7FFB68667D')

                 {
                    uuid: '58A9345E881F48C980498C7FFB68667D'
                 }

This function implements DFS:

function findDFS(objects, id) {
  for (let o of objects || []) {
    if (o.uuid == id) return o
    const o_ = findDFS(o.children, id)
    if (o_) return o_
  }
}

And BFS:

function findBFS(objects, id) {
  const queue = [...objects]
  while (queue.length) {
    const o = queue.shift()
    if (o.uuid == id) return o
    queue.push(...(o.children || []))
  }
}

Here is a similar answer, more lines of code for perhaps better readability.

 const array = [ { uuid: '40E75F3DE56B4B11B3AFBDE46785737B' }, { uuid: '9CEF74766BBB4B9682B7817B43CEAE48' }, { uuid: '34F209A883D3406FBA6BACD9E07DB1D9', children: [{ uuid: 'F429C51BF01C405DA517616E0E16DE4E', children: [{ uuid: '8823CFCE7D4645C68991332091C1A05C' }, { uuid: '58A9345E881F48C980498C7FFB68667D' }] }] }, { uuid: '152488CC33434A8C9CACBC2E06A7E535' }, { uuid: '9152B3DEF40F414BBBC68CACE2F5F6E4' }, { uuid: 'B9A39766B17E4406864D785DB6893C3D' }, { uuid: '3J4H4J5HN6K4344D785DBJ345HSSODF', children: [ { uuid: 'EAB14DD72DA24BB88B4837C9D5276859' }, { uuid: 'FFA80D043380481F8835859A0839512B' }, { uuid: '9679687190354FA79EB9D1CA7B4962B1' } ] } ]; function findContainingObject(array, itemId) { let index = 0, result = null; while (index < array.length && !result) { const item = array[index]; if (item.uuid === itemId) { result = item; } else if (item.children !== undefined) { result = findContainingObject(item.children, itemId); } if (result === null) { index++; } } return result; } console.log(findContainingObject(array, '40E75F3DE56B4B11B3AFBDE46785737B')); console.log(findContainingObject(array, '34F209A883D3406FBA6BACD9E07DB1D9')); console.log(findContainingObject(array, '58A9345E881F48C980498C7FFB68667D')); 

Example using recursion.

 const data = [{ uuid: '40E75F3DE56B4B11B3AFBDE46785737B' }, { uuid: '9CEF74766BBB4B9682B7817B43CEAE48' }, { uuid: '34F209A883D3406FBA6BACD9E07DB1D9', children: [{ uuid: 'F429C51BF01C405DA517616E0E16DE4E', children: [{ uuid: '8823CFCE7D4645C68991332091C1A05C' }, { uuid: '58A9345E881F48C980498C7FFB68667D' }] }] }, { uuid: '152488CC33434A8C9CACBC2E06A7E535' }, { uuid: '9152B3DEF40F414BBBC68CACE2F5F6E4' }, { uuid: 'B9A39766B17E4406864D785DB6893C3D' }, { uuid: '3J4H4J5HN6K4344D785DBJ345HSSODF', children: [{ uuid: 'EAB14DD72DA24BB88B4837C9D5276859' }, { uuid: 'FFA80D043380481F8835859A0839512B' }, { uuid: '9679687190354FA79EB9D1CA7B4962B1' } ] } ]; let find = (data, uuid) => { for (let o of data) { if (o.uuid === uuid) { return o; }; if ('children' in o) { let ro = find(o.children, uuid); if (ro) { return ro; } } } } let result = find(data, '9679687190354FA79EB9D1CA7B4962B1') console.clear(); console.log(result); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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