2017-09-05 246 views
1

我有一个数组,每个项目都是具有唯一ID的对象。某些项目也可能有子项,并且它可以在子项数组中包含子项。我正在尝试使用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' 
         } 
        ] 
       } 
      ] 

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

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

预期产出:

findContainingObject(array, '40E75F3DE56B4B11B3AFBDE46785737B') 

       { 
       uuid: '40E75F3DE56B4B11B3AFBDE46785737B' 
       } 

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

findContainingObject(array, '58A9345E881F48C980498C7FFB68667D') 

       { 
        uuid: '58A9345E881F48C980498C7FFB68667D' 
       } 

回答

4

该函数执行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 || [])) 
    } 
} 
+0

谢谢你的解决方案。如果我不得不查看'B9A39766B17E4406864D785DB6893C3D',我会沿着相同的路线行驶,但价格并不昂贵? –

+0

@VamshiGudipati是的,这将是昂贵的。原始数组来自哪里?服务器端API?数据库?你有访问它吗? –

+0

这是我们创建的拖放界面的输出,我无法控制数据进入。我正在编写一个编译器将这些数据转换为另一种形式的数据 –

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

+0

谢谢@Thijs –

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

+0

顺便说一句,从@skovorodkin回答是我认为最完整的+1 :) – GibboK