2017-09-05 98 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

相關問題