使用每个数组的对象键将嵌套数组递归转换为嵌套对象

时间:2017-06-16 16:06:14

标签: javascript arrays database object data-structures

我想更改此数据结构:

[ { 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  和我的尝试一起。

到目前为止,使用lodash或vanillaJS我只能转换外部数组。 我无法递归地使用_.mapKeys(),for循环或类似的东西来获得所需的结构。我确定我错过了一个愚蠢的观点,但我无法解决这个问题。

非常感谢帮助!

2 个答案:

答案 0 :(得分: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变量的值。三个点...将数组分散到单独的元素中,就像这些元素之间用逗号分隔一样。

答案 1 :(得分: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);