我正在寻找一种紧凑的lodash解决方案,以获取对象数组,然后使用数组中对象的键以及每个键的唯一值创建一个新对象。
[
{
color: "black",
type: "bag",
},
{
color: "red",
type: "pants",
},
{
color: "black",
type: "jacket",
},
]
所需的输出:
{
color: ["black", "red"],
type: ["bag", "pants", "jacket"],
}
谢谢!
答案 0 :(得分:2)
您可以使用lodash#flatMap
和lodash#toPairs
迭代来解决此问题,以创建键和值数组对的扁平版本。将lodash#groupBy
与iteratee函数一起使用,该函数将删除数组对的键Array#shift
,并使用该值作为集合的分组键。最后,对由lodash#mapValues
和lodash#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)