这里有很多类似的问题,但是我找不到满足我需求的问题。我正在寻找一个相对简单的解决方案,该解决方案是如何基于键将数组中的对象堆叠到新数组中。
在示例数据中,我们通过“船”键将对象分组。
原始数据:
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'
}
];
如果有人对此有解决方案,我将不胜感激,至少可以说,我目前的尝试是草率的。
答案 0 :(得分:5)
您可以将对象和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; }
答案 1 :(得分:2)
查找和删除重复的船舶名称,然后为每艘船舶找到人员。
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);
答案 2 :(得分:1)
另一种干净优雅的解决方案将与Lodash一起使用。
首先,使用相关键对数组进行分组。然后,从对象中获取值。
从文档中:
创建一个由键组成的对象,这些键由通过iteratee运行collection每个元素的结果生成。分组值的顺序由它们在集合中出现的顺序决定。每个密钥的对应值是负责生成密钥的元素数组。使用一个参数(值)调用iteratee。
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>
答案 3 :(得分:0)
可能不是表现最好的,但是应该可以。
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.
});
}
答案 4 :(得分:0)
不知道您打算如何使用数据,但是更简洁的数据结构看起来像一个对象,其中船上有人员,而不是一个以冗余方式不断重复出现的船名数组?那么这个数据结构呢?
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));
答案 5 :(得分:0)
这有点不同,因为它是一个带有键的对象,但是这些键包含具有数据的数组,您希望如何查看它。
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
});
}
答案 6 :(得分:0)
这里有另一种方法,首先,我们使用Array.reduce()生成一个对象,该对象将按ship属性对元素进行分组。然后,如果仅包含一个元素,则在生成的Array.map()上使用Object.values()来删除数组。如果您真的不需要最后一步,则该地图可能是可选的。
npm i -g npm
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);
答案 7 :(得分: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));