以递归方式在深层嵌套对象数组中查找对象

时间:2017-09-05 20:34:08

标签: javascript arrays recursion lodash

我有一个数组,每个项目都是一个具有唯一ID的对象。有些项目也可能有子项,并且它可以在子数组中包含子数组。我试图使用Id选择一个项目。

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

下面的代码适用于没有子代的简单数组。我需要一个函数或一个lodash模块,它可以递归搜索整个数组并返回对象(数组中的项目)

findContainingObject(array, '40E75F3DE56B4B11B3AFBDE46785737B')

               {
                 uuid: '40E75F3DE56B4B11B3AFBDE46785737B'
               }

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

findContainingObject(array, '58A9345E881F48C980498C7FFB68667D')

                 {
                    uuid: '58A9345E881F48C980498C7FFB68667D'
                 }

预期产出:

$scope.$id

3 个答案:

答案 0 :(得分:8)

此函数实现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_
  }
}

和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 || []))
  }
}

答案 1 :(得分:1)

这是一个类似的答案,更多的代码行可能更好的可读性。

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'));

答案 2 :(得分:1)

使用递归的示例。

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);