繁体   English   中英

从对象数组中按键创建对象数组

[英]Create array of objects by key from array of objects

这里有很多这样的问题,但我找不到符合我需求的问题。 我正在寻找一个相对简单的解决方案,关于如何根据键将数组中的对象堆叠到新数组中。

在示例数据中,我们通过“船”键对对象进行分组。

原始数据:

 var myObjArray = [
    {
        name:'Malcolm Reynolds',
        ship:'Serenity'
    },
    {
        name: 'Carmen Ibanez',
        ship: 'Rodger Young',
    },
    {
        name: 'Zander Barcalow',
        ship: 'Rodger Young',
    },
    {
        name:'Hoban Washburne',
        ship:'Serenity'
    },
    {
        name:'James Kirk',
        ship:'USS Enterprise'
    }
];

重组数据:

    var myNewObjArray = [
    [{
        name:'Malcolm Reynolds',
        ship:'Serenity'
    },
    {
        name:'Hoban Washburne',
        ship:'Serenity'
    }],
    [{
        name: 'Carmen Ibanez',
        ship: 'Rodger Young',
    },
    {
        name: 'Zander Barcalow',
        ship: 'Rodger Young',
    }],
    {
        name:'James Kirk', // optionally also stick in an array
        ship:'USS Enterprise'
    }
];

如果有人有解决方案,我会很感激,我目前的尝试至少可以说是草率的。

您可以将对象和ship值作为同一组的关键。 对于结果,只取对象的值。

 var data = [{ name: 'Malcolm Reynolds', ship: 'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young' }, { name: 'Zander Barcalow', ship: 'Rodger Young' }, { name: 'Hoban Washburne', ship: 'Serenity' }, { name: 'James Kirk', ship: 'USS Enterprise' }], grouped = Object.values(data.reduce((r, o) => { if (!r[o.ship]) { r[o.ship] = o; return r; } if (!Array.isArray(r[o.ship])) r[o.ship] = [r[o.ship]]; r[o.ship].push(o); return r; }, {})); console.log(grouped); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

一种使用Map的方法

 var data = [{ name: 'Malcolm Reynolds', ship: 'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young' }, { name: 'Zander Barcalow', ship: 'Rodger Young' }, { name: 'Hoban Washburne', ship: 'Serenity' }, { name: 'James Kirk', ship: 'USS Enterprise' }], grouped = Array.from( data .reduce((m, o) => m.set(o.ship, [...(m.get(o.ship) || []), o]), new Map) .values(), a => a.length === 1 ? a[0] : a ); console.log(grouped); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

找到并重复删除船舶名称,然后找到每艘船的人员。

 const myObjArray = [ { name:'Malcolm Reynolds', ship:'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young', }, { name: 'Zander Barcalow', ship: 'Rodger Young', }, { name:'Hoban Washburne', ship:'Serenity' }, { name:'James Kirk', ship:'USS Enterprise' } ]; const ships = myObjArray.map(({ship}) => ship).filter((ship, i, arr) => arr.indexOf(ship) === i); const personnelArray = ships.map(ship => myObjArray.filter(entry => entry.ship === ship)); console.log(personnelArray); 

另一个干净而优雅的解决方案是与Lodash合作

首先,使用相关键对数组进行分组。然后,从对象中获取值。

来自文档:

创建一个对象,该对象由通过iteratee运行集合的每个元素的结果生成的键组成。 分组值的顺序由它们在集合中出现的顺序确定。 每个键的对应值是负责生成密钥的元素数组。 使用一个参数调用iteratee :( value)。

 const myObjArray = [ { name:'Malcolm Reynolds', ship:'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young', }, { name: 'Zander Barcalow', ship: 'Rodger Young', }, { name:'Hoban Washburne', ship:'Serenity' }, { name:'James Kirk', ship:'USS Enterprise' } ]; var result =_.values((_.groupBy(myObjArray , 'ship'))); console.log(result); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script> 

可能不是最高效的,但这应该有效。

var tempObj = {};
myObjArray.forEach((item)=>{
  var ship = item.ship;
  if (!tempObj.hasOwnProperty(ship)) {
    tempObj[ship] = []; //create the key in the key in the obj and init to an empty array
  }
  tempObj[ship].push(item); //add the item to the array
});

var myNewObjArray = [];

for (key in tempObj) {
  myNewObjArray.push([]); //add a new array for each key in the tempObj
  tempObj[key].forEach((item)=>{ //iterate over the array of items in the tempObj for that key
    myNewObjArray[myNewObjArray.length-1].push(item); //add the item to the last array in the object which should have been created.
  });
}

不确定你打算如何使用数据,但是更简洁的数据结构看起来就像船上有员工的对象,而不是一个数组,其中船名以冗余的方式不断重复? 这个数据结构怎么样?

 var myObjArray = [ { name:'Malcolm Reynolds', ship:'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young', }, { name: 'Zander Barcalow', ship: 'Rodger Young', }, { name:'Hoban Washburne', ship:'Serenity' }, { name:'James Kirk', ship:'USS Enterprise' } ]; const staffShips = data => data.reduce((ships, item) => { const ship = ships[item.ship]; if (ship) { ship.push(item.name); } else { ships[item.ship] = [ item.name ]; } return ships; }, {}); console.log(staffShips(myObjArray)); 

这略有不同,因为它是一个带键的对象,但这些键包含数组,其中包含您希望如何看到它的数据。

var newObject = {};

for (var i in myObjArray) {
     var newKey = myObjArray[i].ship.replace(/\s+/g, '');
   if (typeof(newObject[newKey]) == "undefined") newObject[newKey] = [];
   newObject[newKey].push({
        name: myObjArray[i].name, ship: myObjArray[i].ship
   });
}

这里有另一种方法,首先,我们使用Array.reduce()生成一个对象,该对象将按ship属性对元素进行分组。 然后我们在生成的Object.values()上使用Array.map()来删除数组(如果只保存一个元素)。 如果您真的不需要最后一步,那么地图可以是可选的。

 var myObjArray = [ {name:'Malcolm Reynolds', ship:'Serenity'}, {name: 'Carmen Ibanez', ship: 'Rodger Young'}, {name: 'Zander Barcalow', ship: 'Rodger Young'}, {name:'Hoban Washburne', ship:'Serenity'}, {name:'James Kirk', ship:'USS Enterprise'} ]; let res = myObjArray.reduce((acc, obj) => { acc[obj.ship] = acc[obj.ship] || []; acc[obj.ship].push(obj); return acc; }, {}); res = Object.values(res).map(arr => (arr.length <= 1 ? arr[0] : arr)); console.log(res); 
 .as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;} 

在Javascript中,要按属性对对象进行分组,可以使用Array.prototype.reduce()方法将输入数组数据合并为一组结果,按键分组(在本例中为“ship”)。 使用Object.values通过删除键从结果集中提取值

 var data = [ { name: 'Malcolm Reynolds', ship: 'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young' }, { name: 'Zander Barcalow', ship: 'Rodger Young' }, { name: 'Hoban Washburne', ship: 'Serenity' }, { name: 'James Kirk', ship: 'USS Enterprise' }]; var myNewObjArray = data.reduce((res,obj) =>{ const key = obj.ship; if(!res[key]){ res[key] = []; } res[key].push(obj) return res; }, {}); console.log(Object.values(myNewObjArray)); 

暂无
暂无

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

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