我正在处理此对象数组,并尝试根据匹配的主题对其进行过滤和重新排序。数组看起来像这样:
const results = [
{id: 1, subject: 'biology', grade: 10},
{id: 2, subject: 'biology', grade: 3},
{id: 3, subject: 'math', grade: 4},
{id: 4, subject: 'biology', grade: 2},
{id: 5, subject: 'geography', grade: 1},
{id: 6, subject: 'physics', grade: 3}
]
将来可能会增加更多的主题。 通过过多的过滤方法,我可以按照自己的方式排列它们:
var filteredObj = {};
filteredObj['biology'] = this.results.filter(function (result) {
return result.subject === 'biology';
});
filteredObj['math'] = this.results.filter(function (result) {
return result.subject === 'math';
});
filteredObj['physics'] = this.results.filter(function (result) {
return result.subject === 'physics';
});
filteredObj['geography'] = this.results.filter(function (result) {
return result.subject === 'geography';
});
有没有一种更有效的方法?
答案 0 :(得分:5)
您可以使用Array.reduce()
按主题对项目进行分组:
const results = [{"id":1,"subject":"biology","grade":10},{"id":2,"subject":"biology","grade":3},{"id":3,"subject":"math","grade":4},{"id":4,"subject":"biology","grade":2},{"id":5,"subject":"geography","grade":1},{"id":6,"subject":"physics","grade":3}];
const grouped = results.reduce((r, o) => {
r[o.subject] = r[o.subject] || [];
r[o.subject].push(o);
return r;
}, Object.create(null));
console.log(grouped);
创建更通用的groupBy
函数很容易:
const groupBy = (prop, arr) => arr.reduce((r, o) => {
r[o[prop]] = r[o[prop]] || [];
r[o[prop]].push(o);
return r;
}, Object.create(null));
const results = [{"id":1,"subject":"biology","grade":10},{"id":2,"subject":"biology","grade":3},{"id":3,"subject":"math","grade":4},{"id":4,"subject":"biology","grade":2},{"id":5,"subject":"geography","grade":1},{"id":6,"subject":"physics","grade":3}];
const grouped = groupBy('subject', results);
console.log(grouped);
答案 1 :(得分:3)
尝试减少:
const results = [
{id: 1, subject: 'biology', grade: 10},
{id: 2, subject: 'biology', grade: 3},
{id: 3, subject: 'math', grade: 4},
{id: 4, subject: 'biology', grade: 2},
{id: 5, subject: 'geography', grade: 1},
{id: 6, subject: 'physics', grade: 3}
];
const filteredArray = results.reduce((obj, item) => {
if (typeof obj[item.subject] === 'undefined') {
obj[item.subject] = [item];
} else {
obj[item.subject].push(item);
}
return obj;
}, {});
console.log(filteredArray);
带有精美的es6 maps:
const results = [
{id: 1, subject: 'biology', grade: 10},
{id: 2, subject: 'biology', grade: 3},
{id: 3, subject: 'math', grade: 4},
{id: 4, subject: 'biology', grade: 2},
{id: 5, subject: 'geography', grade: 1},
{id: 6, subject: 'physics', grade: 3}
];
const filteredArray = results.reduce((obj, item) => {
const val = obj.get(item.subject) || [];
val.push(item);
obj.set(item.subject, val);
return obj;
}, new Map());
for (const [subj, val] of filteredArray) {
console.log(subj, val.length);
}
// console.log(JSON.stringify([...filteredArray]));
答案 2 :(得分:1)
使用.map()
根据其属性之一对对象数组进行分组:
const results = [{ id: 1, subject: 'biology', grade: 10 },
{ id: 2, subject: 'biology', grade: 3 },
{ id: 3, subject: 'math', grade: 4 },
{ id: 4, subject: 'biology', grade: 2 },
{ id: 5, subject: 'geography', grade: 1 },
{ id: 6, subject: 'physics', grade: 3 }
];
var filtered = {};
results.map((o, i) => {
if (!(o.subject in filtered)) filtered[o.subject] = [];
filtered[o.subject].push(results[i]);
});
console.log(filtered)
在这种情况下,我更喜欢这种方式,而不是.reduce()
,因为概念更简洁,如果属性不存在,我们在新对象中创建它,如果已经在新对象中创建,我们添加元素。