2017-06-16 98 views
0

我想改變這個數據結構:遞歸嵌套的數組轉換成嵌套對象使用對象的密鑰爲每個陣列

[ { sectionName: 'SectionOne', 
    ingredients: [ {ingredient: 'sugar'}, {ingredient: 'flour'} ]}, 
    { sectionName: 'SectionTwo', 
    ingredients: [ {ingredient: 'eggs'}, {ingredient: 'water'} ] }, 
] 

這樣:

{ SectionOne: 
     { sectionName: 'SectionOne', 
     ingredients: { 
      sugar: { ingredient: 'sugar' }, 
      flour: { ingredient: 'flour' } 
      } 
     }, 
{ SectionTwo: 
     { sectionName: 'SectionTwo', 
     ingredients: { 
      eggs: { ingredient: 'eggs' }, 
      water: { ingredient: 'water' } 
      } 
     }, 

} 

換句話說,我喜歡爲每個我想要轉換爲對象的數組使用對象的鍵。

你可以在這個 jsfddle 以及我的嘗試中找到一個數據結構的例子。我只能轉換外層數組。 我無法管理遞歸使用_.mapKeys(),for循環或類似的去達到所需的結構。我確信我錯過了一個愚蠢的觀點,但我無法繞過這一點。

幫助將非常感謝!

回答

1

您可以map數組和構建你的目標很簡單明瞭:

const data = [ 
 
    { sectionName: 'SectionOne', 
 
    ingredients: [ {ingredient: 'sugar'}, {ingredient: 'flour'} ]}, 
 
    { sectionName: 'SectionTwo', 
 
    ingredients: [ {ingredient: 'eggs'}, {ingredient: 'water'} ] }, 
 
]; 
 
    
 
const res = Object.assign(...data.map(el => ({ // for every element 
 
    [el.sectionName]: { 
 
    sectionName: el.sectionName, 
 
    ingredients: Object.assign(...el.ingredients.map(e => ({[e.ingredient]: e}))) // assign each object inside array 
 
    } 
 
    }))) 
 

 
console.log(res) 
 
console.log(res.SectionOne.ingredients.sugar)

這裏[something]符號創建密鑰,它的名字是something變量的值。三個點...將數組分散到單獨的元素中,就像這些元素之間用逗號分隔。

+0

這是一個非常簡潔的語法。它可以工作,但'data.map()'將所有內容都包含在數組中。說,我仍然不能調用'res.sectionOne.ingredients.sugar'。也許迭代一個'for..of loop'或'for'循環會做什麼? – frankydep

+0

@frankydep我編輯了我的答案。現在它創建一個對象,你可以通過'res.sectionOne.ingredients.sugar'訪問你的道具。起初我並沒有意識到你需要一個最終的結果才能成爲一個對象。 – wostex

+0

wostex!非常好的工作!我仍然無法理解爲什麼'Object.assing()'上下文中的'.map()'不會生成數組。是否因爲傳播運算符?還應該'Object.assing()'需要一個目標對象嗎?再次感謝! – frankydep

1

這裏有一個使用reduce的工作解決方案。您可能可以重構這更多:

const sections = [ 
    { sectionName: 'SectionOne', 
    ingredients: 
     [ 
     {ingredient: 'sugar'}, 
     {ingredient: 'flour'} 
     ] 
    }, 
    { sectionName: 'SectionTwo', 
    ingredients: 
     [ 
     {ingredient: 'eggs'}, {ingredient: 'water'} 
     ] 
    }, 
]; 

const result = sections.reduce((accumulator, currentValue) => { 
    const ingredientsObj = currentValue.ingredients.reduce((acc, ingredient) => { 
    acc[ingredient.ingredient] = { 
     ingredient: ingredient.ingredient 
    }; 
    return acc; 
    }, {}); 

    var sectionObject = { 
    sectionName: currentValue.sectionName, 
    ingredients: ingredientsObj 
    } 
    accumulator[currentValue.sectionName] = sectionObject; 
    return accumulator; 

}, {}); 

console.log(result);