Reputation: 443
I have array like bellow:
var array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]
I would like to have output like:
array = [{name: 'abc', age: [17, 89]}, {name: 'cde', age: 20}]
How can achieve it? I tried many solutions like eg:
var result = _(array)
.groupBy('name')
.map(_.spread(_.assign))
.value();
but it's not what I want because I would like to have array of values age.
Upvotes: 1
Views: 95
Reputation: 4806
try this
const data = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]
const groupBy = (arr) => data.reduce((acc, ele)=>( (acc[ele.name] = acc[ele.name] || []).push(ele), acc),{})
const displayAge= v => v.length>1?v.map(e=>e.age):v[0].age
console.log(Object.entries(groupBy(data)).map(([name, v])=>({name, age: displayAge(v)})))
Upvotes: 1
Reputation: 757
Would be easier if you always kept age as an array instead of being Number when only one value is present.
const array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]
const newArray = array.reduce((arr, i) => {
const inArray = arr.findIndex(a => a.name === i.name);
if (inArray < 0) arr.push(i);
else {
if (Array.isArray(arr[inArray].age)) {
arr[inArray].age.push(i.age);
} else {
arr[inArray].age = [arr[inArray].age, i.age];
}
}
return arr;
}, [])
console.log(newArray);
Upvotes: 0
Reputation: 402253
You can create a map (which is constant time lookup), then convert it to an array. Not the prettiest solution, but definitely performant in terms of complexity (linear).
const array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]
const m = new Map();
array.map(x => {
if (!m.has(x.name)) {
m.set(x.name, []);
}
m.get(x.name).push(x.age);
});
console.log(Array.from(m).map(
(x) => Object.assign({'name': x[0], 'age': x[1]})));
Upvotes: 1
Reputation: 151
What about:
var result = array.forEach(a => {
let similar = array.filter(b => b.name == a.name).map(c => c.age);
a.age = similar.length > 1 ? similar : a.age;
}).filter((d,e) => array.indexOf(d) == e);
Upvotes: 0
Reputation: 392
Well I don't understand why aren't you using loops or anything.. You didn't specify format so here have my code in vanila js:
var array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]
for (var i = 0; i < array.length; i++) {
for (var j = i + 1; j < array.length; j++) {
if (array[i].name == array[j].name) {
if (Array.isArray(array[i].age)) {
array[i].age.push(array[j].age)
} else {
var arAge = [array[i].age, array[j].age];
array[i].age = arAge;
}
array.splice(j,1);
j--;
}
}
}
Upvotes: 0