如果具有相同的ID,我想将值合并到数组。 我有一个这样的对象数组。
[
{
id: 'Tony',
type: 'hero',
favorite: 'Rosie',
},
{
id: 'Jane',
type: 'human',
favorite: null,
},
{
id: 'Tony',
type: 'hero',
favorite: 'Lisa',
},
{
id: 'Steve',
type: 'hero',
favorite: 'Jennie',
},
{
id: 'Tony',
type: 'hero',
favorite: 'Jisoo',
},
]
,我想将键favorite
从字符串合并到数组。
我想要这样的输出
[
{
id: 'Tony',
type: 'hero',
favorite: ['Rosie', 'Lisa', 'Jisoo'],
},
{
id: 'Jane',
type: 'human',
favorite: null,
},
{
id: 'Steve',
type: 'hero',
favorite: ['Jennie'],
}
并且我尝试编写如下代码:(from:Sum similar keys in an array of objects)
var obj = [
{
id: 'Tony',
type: 'hero',
favorite: 'Rosie',
},
{
id: 'Jane',
type: 'human',
favorite: null,
},
{
id: 'Tony',
type: 'hero',
favorite: 'Lisa',
},
{
id: 'Steve',
type: 'hero',
favorite: 'Jennie',
},
{
id: 'Tony',
type: 'hero',
favorite: 'Jisoo',
},
];
var holder = {};
const ar = []
obj.forEach(function (d) {
if (holder.hasOwnProperty(d.id)) {
holder[d.id] = ar.push(holder[d.id] + d.favorite);
} else {
holder[d.id] = d.favorite;
}
});
var obj2 = [];
for (var prop in holder) {
obj2.push({ name: prop, favorite: holder[prop] });
}
console.log(obj2);
但是卖出的是
[ { name: 'Tony', favorite: 2 },
{ name: 'Jane', favorite: null },
{ name: 'Steve', favorite: 'Jennie' } ]
我该怎么做?
答案 0 :(得分:4)
您可以使用单个Array.reduce进行此操作,这很可能是最简单,最有效的方法:
var data = [ { id: 'Tony', type: 'hero', favorite: 'Rosie', }, { id: 'Jane', type: 'human', favorite: null, }, { id: 'Tony', type: 'hero', favorite: 'Lisa', }, { id: 'Steve', type: 'hero', favorite: 'Jennie', }, { id: 'Tony', type: 'hero', favorite: 'Jisoo', }, ]
let result = data.reduce((r, {id,type,favorite}) => {
r[id] = r[id] || {id, type, favorite: []}
r[id].favorite.push(favorite)
return r
}, {})
console.log(Object.values(result))
这个想法是对id
进行“分组”,然后在每次迭代时继续推送到favorites
数组。
对于ES5
,您可以按照类似的方式进行操作:
var data = [ { id: 'Tony', type: 'hero', favorite: 'Rosie', }, { id: 'Jane', type: 'human', favorite: null, }, { id: 'Tony', type: 'hero', favorite: 'Lisa', }, { id: 'Steve', type: 'hero', favorite: 'Jennie', }, { id: 'Tony', type: 'hero', favorite: 'Jisoo', }, ]
let result = data.reduce(function(r, c){
r[c.id] = r[c.id] || {id: c.id, type: c.type, favorite: []}
r[c.id].favorite.push(c.favorite)
return r
}, {})
console.log(Object.values(result))
lodash
确实不需要实现这一点。
答案 1 :(得分:0)
将id
与_.group()
分组,然后使用_.map()
和_.mergeWith()
合并每个分组,并将favorite
收集到一个数组中:
const data = [{"id":"Tony","type":"hero","favorite":"Rosie"},{"id":"Jane","type":"human","favorite":null},{"id":"Tony","type":"hero","favorite":"Lisa"},{"id":"Steve","type":"hero","favorite":"Jennie"},{"id":"Tony","type":"hero","favorite":"Jisoo"}]
const result = _(data)
.groupBy('id')
.map(g => _.mergeWith({}, ...g, (o, s, k) => {
if(k !== 'favorite') return // non favorite key are not collected to an array
if(_.isNil(s)) return o // don't add null or undefined to array
return [].concat(o || [], s) // concat other values to array
}))
.value()
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
答案 2 :(得分:0)
在将favorite
属性转换为数组之后,只需遍历数组并构造一个新数组,然后对于具有相同id的下一个元素,推入favorite
数组
let users = [{id: 'Tony', type: 'hero', favorite: 'Rosie',}, {id: 'Jane', type: 'human', favorite: null,}, {id: 'Tony', type: 'hero', favorite: 'Lisa',}, {id: 'Steve', type: 'hero', favorite: 'Jennie',}, {id: 'Tony', type: 'hero', favorite: 'Jisoo',},];
// To combine friends of the same user in an array at property friendNames
let merged = {};
for (let user of users) {
if (typeof merged[user.id] === 'undefined') {
user.favorite = [user.favorite];
merged[user.id] = user;
} else {
merged[user.id].favorite.push(user.favorite)
}
}
console.log(Object.values(merged));
答案 3 :(得分:0)
使用map
和Set
获得此结果。
首先,我们使用Set
字段创建一个新的唯一id
。
我们从中播种一个新的新array
并调用map
方法。
const arr = [
{
id: 'Tony',
type: 'hero',
favorite: 'Rosie',
},
{
id: 'Jane',
type: 'human',
favorite: null,
},
{
id: 'Tony',
type: 'hero',
favorite: 'Lisa',
},
{
id: 'Steve',
type: 'hero',
favorite: 'Jennie',
},
{
id: 'Tony',
type: 'hero',
favorite: 'Jisoo',
},
];
const masterArr = [...new Set(arr.map((e) => e.id))].map(a => ({
id: a,
type: arr.find(x => x.id === a).type,
favorites: arr.filter(x => x.id === a).map(y => y.favorite)
}));
console.log(masterArr);
答案 4 :(得分:0)
您可以在数组上使用reduce。
const arr = [
{
id: 'Tony',
type: 'hero',
favorite: 'Rosie',
},
{
id: 'Jane',
type: 'human',
favorite: null,
},
{
id: 'Tony',
type: 'hero',
favorite: 'Lisa',
},
{
id: 'Steve',
type: 'hero',
favorite: 'Jennie',
},
{
id: 'Tony',
type: 'hero',
favorite: 'Jisoo',
},
]
const out = arr.reduce((result, el)=> {
const id = result.findIndex(e => e.id ===el.id)
if(id> -1){
result[id] = {...result[id], favorite: [...result[id].favorite, el.favorite]}
} else {result.push({...el, favorite: [el.favorite].filter(x => x) })}
return result
}, [])
console.log(out)
答案 5 :(得分:0)
与Lodash:
var data = [ { id: 'Tony', type: 'hero', favorite: 'Rosie', }, { id: 'Jane', type: 'human', favorite: null, }, { id: 'Tony', type: 'hero', favorite: 'Lisa', }, { id: 'Steve', type: 'hero', favorite: 'Jennie', }, { id: 'Tony', type: 'hero', favorite: 'Jisoo', }, ]
var result = _(data).groupBy(a => a.id).map((objs, key) => ({
'id': key,
'type': _.head(objs).type,
'favorite': _.map(objs, 'favorite')
}))
.value();
console.log(result);
<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>