如何按某些 属性 值对对象数组进行分组
How to group array of objects by certain property values
我有两个数组。
一个包含名称的字符串数组
let companies = ['Google', 'Coca Cola,' 'Jonson & Jonson',];
另一个数组包含有人物的对象
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
我的任务是按名字对这些人进行分组
const groups = [
{'Google': [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vlad' company: 'Google', id : 4},
]},
'Jonson & Jonso': [
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
]},
...
]
也许有人知道如何以最简单的方式做到这一点并且无需对 JS 进行额外的迭代?
我可以使用嵌套循环,但它太复杂了。
也许可以用 lodash
做?
另请注意,公司名称的字符串键可能有空格。
非常感谢任何建议。
let employees = [
{name: 'Alina', company: 'Google', id : 1},
{name: 'Vika', company: 'Coca Cola', id : 2},
{name: 'Alex', company: 'Jonson & Jonson', id : 3},
{name: 'Vlad', company: 'Google', id : 4},
{name: 'Fibi', company: 'Coca Cola', id : 5},
{name: 'Joey', company: 'Google', id : 6},
]
function groupBy(arr, property) {
return arr.reduce(function (memo, x) {
if (!memo[x[property]]) { memo[x[property]] = []; }
memo[x[property]].push(x);
return memo;
}, {});
};
console.log(groupBy(employees,'company'));
最简单的方法是:
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
const grouped = groupBy(employees, employee => employee.company);
伙计,如果你在提问之前甚至不检查你的结构是否没有错误,这似乎是对潜在回应者的不尊重。 NVM:/
所以,有固定变量:
let companies = ['Google', 'Coca Cola', 'Jonson & Jonson'];
let employees = [
{name: 'Alina', company: 'Google', id : 1},
{name: 'Vika', company: 'Coca Cola', id : 2},
{name: 'Alex', company: 'Jonson & Jonson', id : 3},
{name: 'Vlad', company: 'Google', id : 4},
{name: 'Fibi', company: 'Coca Cola', id : 5},
{name: 'Joey', company: 'Google', id : 6}]
请注意 companies
是多余的,因为所有需要的信息都在 employees
。
您要查找的结构可能是 Map
。你只需做:
let map = new Map()
employees.forEach((currentValue) => {
map.has(currentValue.company)
? map.get(currentValue.company).push({name: currentValue.name, id: currentValue.id})
: map.set(currentValue.company, [{name: currentValue.name, id: currentValue.id}])
});
要获得此结果(employee
对象中将不再需要字段 company
):
{
Coca Cola: [{
id: 2,
name: "Vika"
}, {
id: 5,
name: "Fibi"
}],
Google: [{
id: 1,
name: "Alina"
}, {
id: 4,
name: "Vlad"
}, {
id: 6,
name: "Joey"
}],
Jonson & Jonson: [{
id: 3,
name: "Alex"
}]
}
回到未来的答案:
许多浏览器尚不支持,但很快就会支持(TC39 的第 3 阶段)并且已经在 polyfill 中可用 core-js)是数组对象上的新 groupBy
方法。
这将允许您像这样直接执行此操作:
employees.groupBy(employee => employee.company);
甚至:
employees.groupBy(({company}) => company);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/groupBy
由于您走的是简单路线,所以它会稍微长一些。
let companies = ['Google', 'Coca Cola,' 'Jonson & Jonson',];
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
//Let's create an intermediate object
let interm = {};
/*This would create an object like
{
Key:[],
Key2:[],
...
}
*/
companies.forEach((each)=>{
interm[`${each}`] = [];
})
/*filling that interm a
Object with values like
{
'Google':[
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Joey' company: 'Google', id : 6}
],
Coca Cola:[
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Fibi' company: 'Coca Cola', id : 5},
],
"Jonson & Jonson":[
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
]
}
*/
employee.forEach((each)=>{
if(companies.indexOf(each.company) != -1)
interm[`${each.company}`].push(each)
})
//Now our intermediate data is ready
//We need to convert to our desirable format
let finalArray = []
Object.keys(interm).forEach((each)=>{
finalArray.push({each:interm[`${each}`]})
})
console.log(finalArray)
我有两个数组。 一个包含名称的字符串数组
let companies = ['Google', 'Coca Cola,' 'Jonson & Jonson',];
另一个数组包含有人物的对象
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
我的任务是按名字对这些人进行分组
const groups = [
{'Google': [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vlad' company: 'Google', id : 4},
]},
'Jonson & Jonso': [
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
]},
...
]
也许有人知道如何以最简单的方式做到这一点并且无需对 JS 进行额外的迭代?
我可以使用嵌套循环,但它太复杂了。
也许可以用 lodash
做?
另请注意,公司名称的字符串键可能有空格。
非常感谢任何建议。
let employees = [
{name: 'Alina', company: 'Google', id : 1},
{name: 'Vika', company: 'Coca Cola', id : 2},
{name: 'Alex', company: 'Jonson & Jonson', id : 3},
{name: 'Vlad', company: 'Google', id : 4},
{name: 'Fibi', company: 'Coca Cola', id : 5},
{name: 'Joey', company: 'Google', id : 6},
]
function groupBy(arr, property) {
return arr.reduce(function (memo, x) {
if (!memo[x[property]]) { memo[x[property]] = []; }
memo[x[property]].push(x);
return memo;
}, {});
};
console.log(groupBy(employees,'company'));
最简单的方法是:
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
const grouped = groupBy(employees, employee => employee.company);
伙计,如果你在提问之前甚至不检查你的结构是否没有错误,这似乎是对潜在回应者的不尊重。 NVM:/
所以,有固定变量:
let companies = ['Google', 'Coca Cola', 'Jonson & Jonson'];
let employees = [
{name: 'Alina', company: 'Google', id : 1},
{name: 'Vika', company: 'Coca Cola', id : 2},
{name: 'Alex', company: 'Jonson & Jonson', id : 3},
{name: 'Vlad', company: 'Google', id : 4},
{name: 'Fibi', company: 'Coca Cola', id : 5},
{name: 'Joey', company: 'Google', id : 6}]
请注意 companies
是多余的,因为所有需要的信息都在 employees
。
您要查找的结构可能是 Map
。你只需做:
let map = new Map()
employees.forEach((currentValue) => {
map.has(currentValue.company)
? map.get(currentValue.company).push({name: currentValue.name, id: currentValue.id})
: map.set(currentValue.company, [{name: currentValue.name, id: currentValue.id}])
});
要获得此结果(employee
对象中将不再需要字段 company
):
{
Coca Cola: [{
id: 2,
name: "Vika"
}, {
id: 5,
name: "Fibi"
}],
Google: [{
id: 1,
name: "Alina"
}, {
id: 4,
name: "Vlad"
}, {
id: 6,
name: "Joey"
}],
Jonson & Jonson: [{
id: 3,
name: "Alex"
}]
}
回到未来的答案:
许多浏览器尚不支持,但很快就会支持(TC39 的第 3 阶段)并且已经在 polyfill 中可用 core-js)是数组对象上的新 groupBy
方法。
这将允许您像这样直接执行此操作:
employees.groupBy(employee => employee.company);
甚至:
employees.groupBy(({company}) => company);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/groupBy
由于您走的是简单路线,所以它会稍微长一些。
let companies = ['Google', 'Coca Cola,' 'Jonson & Jonson',];
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
//Let's create an intermediate object
let interm = {};
/*This would create an object like
{
Key:[],
Key2:[],
...
}
*/
companies.forEach((each)=>{
interm[`${each}`] = [];
})
/*filling that interm a
Object with values like
{
'Google':[
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Joey' company: 'Google', id : 6}
],
Coca Cola:[
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Fibi' company: 'Coca Cola', id : 5},
],
"Jonson & Jonson":[
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
]
}
*/
employee.forEach((each)=>{
if(companies.indexOf(each.company) != -1)
interm[`${each.company}`].push(each)
})
//Now our intermediate data is ready
//We need to convert to our desirable format
let finalArray = []
Object.keys(interm).forEach((each)=>{
finalArray.push({each:interm[`${each}`]})
})
console.log(finalArray)