javascript 在javascript中按属性对对象进行分组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15887900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Group objects by property in javascript
提问by Anurag
How to convert this:
如何转换这个:
[
{food: 'apple', type: 'fruit'},
{food: 'potato', type: 'vegetable'},
{food: 'banana', type: 'fruit'},
]
into this:
进入这个:
[
{type: 'fruit', foods: ['apple', 'banana']},
{type: 'vegetable', foods: ['potato']}
]
using javascript or underscore
使用 javascript 或下划线
回答by Anurag
Assuming the original list is contained in a variable named list
:
假设原始列表包含在名为 的变量中list
:
_
.chain(list)
.groupBy('type')
.map(function(value, key) {
return {
type: key,
foods: _.pluck(value, 'food')
}
})
.value();
回答by Ian
Without using underscore:
不使用下划线:
var origArr = [
{food: 'apple', type: 'fruit'},
{food: 'potato', type: 'vegetable'},
{food: 'banana', type: 'fruit'}
];
/*[
{type: 'fruit', foods: ['apple', 'banana']},
{type: 'vegetable', foods: ['potato']}
]*/
function transformArr(orig) {
var newArr = [],
types = {},
i, j, cur;
for (i = 0, j = orig.length; i < j; i++) {
cur = orig[i];
if (!(cur.type in types)) {
types[cur.type] = {type: cur.type, foods: []};
newArr.push(types[cur.type]);
}
types[cur.type].foods.push(cur.food);
}
return newArr;
}
console.log(transformArr(origArr));
DEMO:http://jsfiddle.net/ErikE/nSLua/3/
演示:http : //jsfiddle.net/ErikE/nSLua/3/
Credit goes to @ErikEfor improving/reducing my original code to help with redundancy I had :)
幸得@ErikE为提高/降低我的原代码,以帮助冗余我不得不:)
回答by Obi
Here is a slightly different but more generic version of @Ian's answer
这是@Ian 答案的一个稍微不同但更通用的版本
Caveat: the result is slightly different from the OP requirement, but others like me who stumble on this question might benefit from a more generic answer IMHO
警告:结果与 OP 要求略有不同,但像我这样偶然发现这个问题的其他人可能会受益于更通用的答案恕我直言
var origArr = [
{food: 'apple', type: 'fruit'},
{food: 'potato', type: 'vegetable'},
{food: 'banana', type: 'fruit'}
];
function groupBy(arr, key) {
var newArr = [],
types = {},
newItem, i, j, cur;
for (i = 0, j = arr.length; i < j; i++) {
cur = arr[i];
if (!(cur[key] in types)) {
types[cur[key]] = { type: cur[key], data: [] };
newArr.push(types[cur[key]]);
}
types[cur[key]].data.push(cur);
}
return newArr;
}
console.log(groupBy(origArr, 'type'));
You can find a jsfiddle here
回答by Ori Drori
An ES6 solution to this old question:
这个老问题的 ES6 解决方案:
Iterate using Array#reduce
, and collect the items by group into a Map
. Use spread to convert the Map#values
back into array:
迭代 using Array#reduce
,并按组将项目收集到Map
. 使用 spread 将Map#values
返回转换为数组:
const data = [
{food: 'apple', type: 'fruit'},
{food: 'potato', type: 'vegetable'},
{food: 'banana', type: 'fruit'},
];
const result = [...data.reduce((hash, { food, type }) => {
const current = hash.get(type) || { type, foods: [] };
current.foods.push({ food });
return hash.set(type, current);
}, new Map).values()];
console.log(result);
回答by jcreamer898
var foods = [
{food: 'apple', type: 'fruit'},
{food: 'potato', type: 'vegetable'},
{food: 'banana', type: 'fruit'}
];
var newFoods = _.chain( foods ).reduce(function( memo, food ) {
memo[ food.type ] = memo[ food.type ] || [];
memo[ food.type ].push( food.food );
return memo;
}, {}).map(function( foods, type ) {
return {
type: type,
foods: foods
};
}).value();
回答by agershun
You can group array of objects by one of fields with Alasql library. This example compact arrays exactly as in your example:
您可以使用 Alasql 库按字段之一对对象数组进行分组。此示例紧凑数组与您的示例完全相同:
var res = alasql('SELECT type, ARRAY(food) AS foods FROM ? GROUP BY type',[food]);
Try this example at jsFiddle.
在 jsFiddle试试这个例子。
回答by Justin Levine
You could also use other ES6 Features such as:
您还可以使用其他 ES6 功能,例如:
function groupArray(arr, groupBy, keepProperty) {
let rArr = [], i;
arr.forEach(item => {
if((i = rArr.findIndex(obj => obj[groupBy] === item[groupBy])) !== -1)
rArr[i][`${keepProperty}s`].push(item[keepProperty]);
else rArr.push({
[groupBy]: item[groupBy],
[`${keepProperty}s`]: [item[keepProperty]]
});
});
return rArr;
}
groupArray(yourArray, 'type', 'food');