Home > other >  using a second array count unique values in array
using a second array count unique values in array

Time:11-22

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

Show code snippet

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>

  • Related