-1

If you have an array as input, that contains a certain number of subarrays like so:

[0, 0], [0, 1], [1, 0], [0, 0], [0, 1]

How would you code a function that outputs all elements without duplicates and a function that counts each occurence of the individual elements?

So that the output would be:

[0, 0], [0, 1], [1, 0]

and

2, 2, 1

I've tried the solutions for this question: Counting the occurrences / frequency of array elements, but since javascript can't compare arrays, those didn't work.

4 Answers4

1

Convert every subarray to a string using join.

Use Set to deduplicate then reconvert to Array

Then re-map to original sub array format.

const input = [
[0, 0],
[0, 1],
[1, 0],
[0, 0],
[0, 1],
];


function getUniquesSubArr(input){

    return Array.from(
             new Set(
               input.map(el => el.join(','))
             )
           )
           .map(el => el.split(','))
}

let uniques = getUniquesSubArr(input);

console.log(uniques); // [ [ '0', '0' ], [ '0', '1' ], [ '1', '0' ] ]

About counting occurrences:

  • still convert subarray to index a temporary data structure used for counting
  • add unique elements to the accumulator if not exists
  • increment count if exists
  • will return a data structure with value of sub array and count number
 function countOcc(input){
    return Object.values(input.reduce((acc, el) =>{
        let elStr=el.join(',');
        if(!acc[elStr]){
            acc[elStr]={}
            acc[elStr].value=el;
            acc[elStr].count=0;
        }
        acc[elStr].count++;

        return acc;
    }, {}))
}



console.log(countOcc(input)); // [ { value: [ 0, 0 ], count: 2 },  { value: [ 0, 1 ], count: 2 },{ value: [ 1, 0 ], count: 1 }]

if you like just the count ... well not really recommended IMHO bu just

 console.log(countOcc(input).map(el=>el.count)); // [ 2, 2, 1 ]
koalaok
  • 5,075
  • 11
  • 47
  • 91
1

Using Array#reduce to iterate through and accumulate the arrays.

This will output the result to res in the form:

[frequency: number, subArray: [number, number]][].

const data = [ [0, 0], [0, 1], [1, 0], [0, 0], [0, 1], ];

const seen = [];
const res = data.reduce((acc, curr) => {
  const str = JSON.stringify(curr);
  const idx = seen.indexOf(str);
  idx === -1 ? (seen.push(str), acc.push([0, curr])) : acc[idx][0]++;
  return acc;
}, []);

console.log("count: ", res.map(([freq]) => freq));
console.log("items: ", res.map(([, arr]) => arr));
console.log("full: ", res);
lejlun
  • 4,140
  • 2
  • 15
  • 31
0

Maybe not the best way of doing it but it works too with JSON.stringify() and Array.prototype.reduce() :

const arrays = [[0, 0], [0, 1], [1, 0], [0, 0], [0, 1]]

const res = arrays.reduce((acc, arr) => {
  const stringified = JSON.stringify(arr)
  acc[stringified] ? acc[stringified]++ : acc[stringified] = 1
  return acc
}, {})

console.log(Object.keys(res).map(stringified => JSON.parse(stringified)))

console.log(Object.values(res))
Namysh
  • 3,717
  • 2
  • 9
  • 17
0

With some trick, you can achieve it like below. The trick is convert arrays into concatenated strings and then count the number of indexes;

const sourceArray  = [[0, 0], [0, 1], [1, 0], [0, 0], [0, 1]].map(r=> r.join(""));
const searchArray = [[0, 0], [0, 1], [1, 0]].map(r=> r.join(""));

const result = searchArray.map(r=> sourceArray.reduce((acc, el) => (el === r ? acc + 1 : acc), 0));

console.log(result);

Finding all indexes of a given element is taken from this so answer.

Eldar
  • 9,781
  • 2
  • 10
  • 35