简体   繁体   English

在JavaScript中过滤对象数组

[英]Filter array of object in javascript

I am creating a project using JavaScript. 我正在使用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 = {} 这是我正在使用的方法。但是不知道如何实现此变量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++){


         }

Use reduce : 使用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; } 

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 {} 首先在数组上使用reduce()并将累加器设置为空对象{}
  • During each iteration get id and postedUserId is separate variable using Destructuring. 在每次迭代过程中,使用Destructuring获取idpostedUserId是单独的变量。 And use spread operator to get rest of properties. 并使用传播运算符获取其余属性。
  • Then check if is there already an item present of the current id in accumulator. 然后检查累加器中是否已经存在当前id的项目。
  • If its there then push the postedUserId to its postedUsers array. 如果存在,则将postedUserId推送到其postedUsers数组。
  • If that key is not present then set the key( id ) on accumulator to an object with postedUsers as empty array. 如果该键不存在,则将累加器上的键( id )设置为一个对象, postedUsers作为空数组。

 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. 您在注释中询问了简单的for循环,所以这是该版本。

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

You can use reduce and group the postedUser and keep the first postedUserId 您可以使用reduce和分组postedUser并保留第一个postedUserId

  • First loop through arr1 array and use id as key on object we are building 首先循环遍历arr1数组,并使用id作为我们要构建的对象的键
  • 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 首先,如果object已具有值,则检查postedUserId如果不存在,则检查postedUserId添加当前ID,否则不添加
  • Now push the postedUserId in postedUser 现在将postedUserIdpostedUserId 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)) 

I would use a temporary Map for the grouping you want. 我会使用临时Map进行分组。

 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. 这将优先使用最后一次出现相同ID的数据。 If you want the first to have precedence, then just reverse the array 如果您希望第一个具有优先级,则只需反转数组

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM