用lodash中的值将对象数组转换为分组对象

时间:2018-06-23 17:22:31

标签: javascript lodash

我正在寻找一种紧凑的lodash解决方案,以获取对象数组,然后使用数组中对象的键以及每个键的唯一值创建一个新对象。

[
    {
        color: "black",
        type: "bag",
    },
    {
        color: "red",
        type: "pants",
    },
    {
        color: "black",
        type: "jacket",
    },
]

所需的输出:

{
    color: ["black", "red"],
    type: ["bag", "pants", "jacket"],
}

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以使用lodash#flatMaplodash#toPairs迭代来解决此问题,以创建键和值数组对的扁平版本。将lodash#groupBy与iteratee函数一起使用,该函数将删除数组对的键Array#shift,并使用该值作为集合的分组键。最后,对由lodash#mapValueslodash#flatten组成的迭代器使用lodash#uniq,以展平数组并仅获得每个分组数组的唯一值。请注意,函数组合使用lodash#flow来构成连续的函数参数以形成一个函数结果。

var result = _(array)
  .flatMap(_.toPairs)
  .groupBy(v => v.shift())
  .mapValues(_.flow(_.flatten, _.uniq))
  .value();

var array = [
    {
        color: "black",
        type: "bag",
    },
    {
        color: "red",
        type: "pants",
    },
    {
        color: "black",
        type: "jacket",
    }
];

var result = _(array)
  .flatMap(_.toPairs)
  .groupBy(v => v.shift())
  .mapValues(_.flow(_.flatten, _.uniq))
  .value();
  
console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

答案 1 :(得分:1)

我看不到一个可以为您完成此任务的函数,因此这是一个仅使用lodash函数即可通过许多简单步骤解决问题的解决方案。

const listOfPairs = _.flatten(_.map(input, _.toPairs))

将对象列表转换为[键,值]对的列表

listOfPairs = [
  [ 'color', 'black' ],
  [ 'type', 'bag' ],
  [ 'color', 'red' ],
  [ 'type', 'pants' ] ]

现在,我们可以将它们按每对中第一个位置的值分组。

const indexByKeyToValues = _.toPairs(_.groupBy(listOfPairs, _.head))

这给了我们

indexByKeyToValues = [
  [ 'color', [ ['color', 'black'], ['color', 'red'] ] ],
  [ 'type', [ ['type', 'bag'], ['type', 'pants'] ] ] ]

然后,在值数组上映射以选择最后一个元素(输入映射中的原始值)

const pairsOfKeyAndValue = _.map(indexByKeyToValues, ([k, vs]) => [k, _.map(vs, _.last)])

快要出现了

pairsOfKeyAndValue = [
  [ 'color', [ 'black', 'red' ] ],
  [ 'type', [ 'bag', 'pants' ] ] ]

我们只需要使用这些对来重建对象

const result = _.fromPairs(pairsOfKeyAndValue)

整个“变换成对的序列和从成对的序列到映射或从成对的序列变换映射”的技巧在函数式编程中确实很常见。完成此操作后,找出其余步骤就不太麻烦了。

希望这为您提供了一个一般性的想法,可以在将来用来解决此类问题。

答案 2 :(得分:1)

使用内置的功能。它更快,更短并且更容易推理。

const arr = [{color: "black",type: "bag",},{color: "red",type: "pants",},{color: "black",type:"jacket",}],
obj = arr.reduce((h, y) => {
  Object.keys(y).forEach(k => {
    if (!h[k]) {
      h[k] = []
      h[k].push(y[k])
    } else if (!h[k].includes(y[k])) h[k].push(y[k])
  })
  return h
}, {})
console.log(obj)