Clash Royale CLAN TAG#URR8PPP
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?
filteredArray['biology']
var filteredArray = ;
filteredArray['biology']
3 Answers
3
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);
Object.create(null)
{}
r[o.subject] ||
toString
grouped.hasOwnProperty('biology')
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:
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()
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Array is not a key-value store...
filteredArray['biology']
looks incorrect to me.– Kosh Very
yesterday