简体   繁体   English

有没有更有效的方法来过滤这个对象数组?

[英]Is there a more efficient way to filter this array of objects?

I'm working with this array of objects and I try to filter and reorder it based on matching subjects . 我正在使用这个对象数组,我尝试根据匹配的主题对其进行过滤和重新排序。 The array looks somewhat like this: 该数组看起来有点像这样:

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}
]

It's likely there will be added more subjects in the future. 未来很可能会增加更多的主题。 With an over-abundant filtering method, I can arrange them the way I want: 使用过多的过滤方法,我可以按照我想要的方式安排它们:

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';
});

Is there a way more efficient way of doing this? 有没有办法更有效地这样做?

You can use Array.reduce() to group the items by subject: 您可以使用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); 

And it's easy to create a more generic groupBy function: 并且很容易创建一个更通用的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); 

Try 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 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); 

With fancy es6 maps : 使用花哨的es6 地图

 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])); 

Using .map() to group an array of objects based of one of its properties: 使用.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) 

In this case, I prefer this way instead of .reduce() because the concept is more neat, if a property doesn't exist we create it in a new object, if is already created in the new object, we add the element. 在这种情况下,我更喜欢这种方式而不是.reduce()因为概念更整洁,如果属性不存在我们在新对象中创建它,如果已经在新对象中创建,我们添加元素。

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

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