Reputation: 1118
I am creating a project using JavaScript. I am stuck in the problem while filtering the array of object: Here is the array:
var arr1 = [{
"name": "harkaran",
"lname": "sofat",
"userId": 49,
"postedUserId": 52,
"id": 21,
},{
"name": "harkaran",
"lname": "sofat",
"userId": 49,
"postedUserId": 57,
"id": 21,
}]
final array should look like:
[{
"name": "harkaran",
"lname": "sofat",
"userId": 49,
"postedUserId": 52,
"id": 21,
postedUsers:[52,57]
}]
I am trying to creating new object. Here is the approach i am using.But dont know how can i achieve this var arr =[] let obj = {}
obj['name'] = "";
obj['lname'] = "";
obj['userId'] = "";
obj['postedUserId'] = "";
obj['id'] = "";
obj['postedUsers'] = [];
arr.push(obj);
for(var i=0; i<arr1.length; i++){
}
Upvotes: 1
Views: 75
Reputation: 36594
First of all this is not called filtering. Its called grouping. You can do that in following steps:
reduce()
on array and set accumulator to an empty object {}
id
and postedUserId
is separate variable using Destructuring. And use spread operator to get rest of properties.id
in accumulator.postedUserId
to its postedUsers
array.id
) on accumulator to an object with postedUsers
as empty array.var arr1 = [{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":52,"id":21,},{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":57,"id":21,}];
const res = arr1.reduce((ac,{id,postedUserId,...rest}) => {
if(!ac[id]) ac[id] = {id,postedUserId,postedUsers:[],...rest};
ac[id].postedUsers.push(postedUserId);
return ac;
},{})
console.log(Object.values(res))
You asked in the comments for simple for
loop so here is the version of that.
var arr1 = [{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":52,"id":21,},{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":57,"id":21,}];
let res = {};
for(let i = 0; i<arr1.length; i++){
let {id,postedUserId,...rest} = arr1[i];
if(!res[id]) res[id] = {id,postedUserId,postedUsers:[],...rest};
res[id].postedUsers.push(postedUserId);
}
console.log(Object.values(res))
Upvotes: 1
Reputation: 351228
I would use a temporary Map
for the grouping you want.
var arr1 = [{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":52,"id":21,},{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":57,"id":21,}];
const map = new Map(arr1.map(o => [o.id, { ...o, postUsersId: [] }]));
arr1.forEach(o => map.get(o.id).postUsersId.push(o.postedUserId));
const res = [...map.values()];
console.log(res);
This will give precedence to the data given with the last occurrence of the same id. If you want the first to have precedence, then just reverse the array
Upvotes: 0
Reputation: 37775
You can use reduce and group the postedUser
and keep the first postedUserId
arr1
array and use id
as key on object we are buildingobject
already has value, than check for postedUserId
if it's not there add the current id else don'tpostedUserId
in postedUser
var arr1 = [{"name": "harkaran","lname": "sofat","userId": 49,"postedUserId": 52,"id": 21,}, {"name": "harkaran","lname": "sofat","userId": 49,"postedUserId": 57,"id": 21,}]
let final = arr1.reduce((op,{id,...rest})=>{
let postedUserId = rest.postedUserId
if(op[id] && op[id].postedUserId){
delete rest.postedUserId
}
op[id] = op[id] || {...rest,postedUser:[]}
op[id].postedUser.push(postedUserId)
return op
},{})
console.log(Object.values(final))
Upvotes: 0
Reputation: 44145
Use reduce
:
var arr1 = [{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":52,"id":21,},{"name":"harkaran","lname":"sofat","userId":49,"postedUserId":57,"id":21,}];
const res = Object.values(arr1.reduce((acc, { postedUserId, name, ...rest }) => {
acc[name] = acc[name] || { name, ...rest, postedUserId, postedUsers: [] };
acc[name].postedUsers = [].concat(acc[name].postedUsers, postedUserId);
return acc;
}, {}));
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
Upvotes: 1