I’d like to use this vector of keys
const vec_of_vals = ["one", "two", "three", "four"]
to group and filter an array of objects
const data = [
{grade: "one"},
{grade: "one"},
{grade: "one"},
{grade: "two"},
{grade: "four"},
{grade: "four"},
{grade: "four"},
{grade: "four"},
{grade: "five"},
{grade: "five"},
{grade: "five"},
{grade: "six"}
]
And I’ve found posts that can help me to do this, but they don’t include an empty "three"
array which is in my initial vec_of_vals
Here’s what I’ve tried
function groupByKey(array, key) {
return array.reduce((hash, obj) => {
if (obj[key] === undefined) return hash;
return Object.assign(hash, {
[obj[key]]: (hash[obj[key]] || []).concat(obj),
});
}, {});
}
groupByKey(
data.filter((x) => vec_of_vals.includes(x.grade)),
"grade"
);
But this wont give me the empty three
array AND it doesn’t keep the original order of my data!. As a visual here is my desired output:
Desired Output
let desired_output = {
"one" : [
{grade: "one"},
{grade: "one"},
],
"two" : [
{grade: "two"},
],
"three" : [],
"four" : [
{grade: "four"},
{grade: "four"},
{grade: "four"},
{grade: "four"}
]
}
How do I change the groupByKey
function to not only group by grade
but insert any missing grades and remove any grades that are not in the original key as well as maintain the order of the original vec_of_vals
?
2
Answers
You could use
Array::reduce()
on your result grades:Or you could iterate your data array (which is twice faster):
And the benchmark:
One possible and pretty straightforward approach would be based on two single
reduce
tasks.First one reduces the
data
array into an object which groups and collects the data items each by itsgrade
-value …The final result already can be computed from both, the also provided grade-precedence list (what the OP calls "vector of keys" or
vec_of_vals
) and the just processedgradeCollection
.In order to align the
result
object’s key-value pairs (entries) with the grade-values of the already mentionedgradePrecedenceList
(formerly known asvec_of_vals
) one doesreduce
the latter, creating with each iteration an entry where the key equals the currentgrade
-value and the value gets looked up from the before createdgradeCollection
by the samegrade
-value. In case of an unsuccessful lookup one would assign an empty array instead.… executable example code which does prove the above said …