Karan
Karan

Reputation: 1118

Filter array of object in javascript

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

Answers (4)

Maheer Ali
Maheer Ali

Reputation: 36594

First of all this is not called filtering. Its called grouping. You can do that in following steps:

  • First use reduce() on array and set accumulator to an empty object {}
  • During each iteration get id and postedUserId is separate variable using Destructuring. And use spread operator to get rest of properties.
  • Then check if is there already an item present of the current id in accumulator.
  • If its there then push the postedUserId to its postedUsers array.
  • If that key is not present then set the key(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

trincot
trincot

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

Code Maniac
Code Maniac

Reputation: 37775

You can use reduce and group the postedUser and keep the first postedUserId

  • First loop through arr1 array and use id as key on object we are building
  • First we check for the id if the object already has value, than check for postedUserId if it's not there add the current id else don't
  • Now push the postedUserId in postedUser
  • Get the values from final in the end

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

Jack Bashford
Jack Bashford

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

Related Questions