There are many posts on counting unique values in arrays, but I want to count the unique values in an array based on a second array. Specifically: I want to count the distinct occurrences within arr
, but of all the values within grade
arr = [
"12D","12D","12D",
"12C","12C","12C","12C","12C",
"12B","12B","12B","12B","12B",
"12B","12B",
"12A","12A","12A","12A","12A",
"12A","12A","12A","12A","12A",
"12A","12A"
]
grade = ["13B", "13A", "12D", "12C", "12B", "12A"]
result = arr.filter(item => grade.includes(item))
.reduce((acc, val) => {
acc[val] = acc[val] === undefined ? 1 : acc[val] = 1;
return acc;
}, {});
Current Result
My current result does count up the unique occurances
{ '12D': 3, '12C': 5, '12B': 7, '12A': 12 }
Desired Output
but I want to include ALL the values within grade inside my final object (and in the order of grade
]
desired_result = {
'13B': 0,
'13A': 0,
'12D': 3,
'12C': 5,
'12B': 7,
'12A': 12
}
Is it possible to perform this reduce using a second vector?
CodePudding user response:
Another approach would be to start off with the grades and build a frequency table as follows. Then you can invoke Object.fromEntries()
on the resulting array of array pairs:
const result = Object.fromEntries(
grade.map(grade => [grade, arr.filter(g => g === grade).length])
);
DEMO
const arr = ["12D","12D","12D","12C","12C","12C","12C","12C","12B","12B","12B","12B","12B","12B","12B","12A","12A","12A","12A","12A","12A","12A","12A","12A","12A","12A","12A"];
const grade = ["13B", "13A", "12D", "12C", "12B", "12A"];
const result = Object.fromEntries(
grade.map(grade => [grade, arr.filter(g => g === grade).length])
);
console.log( result );
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You could map grades as entries and take the object as start value of reduce.
const
array = ["12D", "12D", "12D", "12C", "12C", "12C", "12C", "12C", "12B", "12B", "12B", "12B", "12B", "12B", "12B", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A"],
grade = ["13B", "13A", "12D", "12C", "12B", "12A"],
result = array.reduce(
(acc, val) => {
if (val in acc) acc[val] ;
return acc;
},
Object.fromEntries(grade.map(g => [g, 0]))
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>