1

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++){


         }
11
  • 1
    Why is there a postedUserId in the final answer? Commented Jun 9, 2019 at 7:20
  • postedUserId is unique. Commented Jun 9, 2019 at 7:23
  • So the first one stays, and the first and all the rest go into the array? Commented Jun 9, 2019 at 7:23
  • yes...........@ Jack Bashford Commented Jun 9, 2019 at 7:24
  • OK, edited my answer, how does that look? Commented Jun 9, 2019 at 7:24

4 Answers 4

1

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; }

Sign up to request clarification or add additional context in comments.

Comments

1

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))

3 Comments

You missed postedUserId in final output mate
@CodeManiac You are right but I consider OP had put that mistakenly. Because there is no point to have postedUserId when there is an array of postedUsers
that's clearly mentioned by OP in comments so i pointed out Ref
0

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))

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.