lodash:从对象数组

时间:2017-05-20 22:55:55

标签: javascript arrays grouping lodash

我最近一直在使用lodash而我喜欢它。所以我正在努力学习它。

在过去的两天里,我一直试图弄清楚如何做以下事情,但没有取得多大成功:考虑一个对象数组,每个对象都有一个属性props中的对象数组......

let items = [{
  name: 'first',
  props: [{
    id: 1,
    name: 'one'
  }, {
    id: 2,
    name: 'two'
  }]
}, {
  name: 'second',
  props: [{
    id: 2,
    name: 'two'
  }]
}, {
  name: 'third',
  props: [{
    id: 1,
    name: 'one'
  }]
}];

...我想创建一个对象数组,其中包含props中所有项目中的每个属性,每个属性都有items属性,所有项目都包含该属性,如下所示:

[{
  id: 1,
  name: 'one',
  items : [] // array containing objects `first` and 'third'
},{
  id: 2,
  name: 'two',
  items: [] // array containing objects `first` and 'second'
}]

我尝试了各种组合,灵感来自this question的答案,这似乎是我能找到的最接近我正在尝试做的事情。我认为我真正的阻挡者是,在尝试创建一个数组时独特的道具(我要将项目映射到其中)并尝试使用...

_(items).chain().flatten().pluck('props').unique().value()

...与this answer一样,它告诉我.chain(...).flatten(...).pluck不是函数。我也尝试使用.map而不是.pluck,但我想并不是所有在Underscore中工作的东西都适用于Lodash(我不知道具体的差异,我只是读Lodash最初是从Underscore分叉的)。 / p>

注意 我知道如何使用经典for来执行此操作 ,这只是一个练习。我没有实际用途。

我只是想学会充分发挥lodash的潜力。如果你知道怎么做,你甚至不需要解释。我会console.log()每一步,直到我明白发生了什么。另外,如果您认为我的问题名称可以改进,为了更好地编制索引,考虑到我想要实现的目标,我愿意接受建议。

理想情况下,答案应该是一系列lodash方法,而不是声明中间变量。我很确定它是可行的(这就是我要问的原因)。当然,步骤越少越好 - 我认为它会影响现实生活中的性能,但这不是一个问题 - 我知道大多数时候,在追求性能时,经典的for循环很难被击败。

1 个答案:

答案 0 :(得分:1)

首先,让我们将每个项目转换为带有项目名称的道具数组,展平这个数组数组,其余部分应该更容易。

 _(data)
  .chain()
  .flatMap(({ props, name }) => _.map(props, p => ({
    id: p.id,
    name: p.name,
    item: name
  })))
  .groupBy(p => p.id)
  .map(props => ({
    id: _.head(props).id,
    name: _.head(props).name,
    items: _.map(props, p => p.item)
  }))
  .value();