1

Input : ['A', 'B', 'C', 'A', 'D', 'B', 'B', 'A', 'D']

Expected output : 'B'

The output should be the element with higher occurrence. If there are two or more elements which shares the same number of occurrence, then the element which reaches the maximum count earlier in the array should be the expected output. In the above case, 'B' and 'A' has count of 3. Since 'B' reaches the max count earlier than 'A', 'B' should be the output.

I have already found the solution for this.

My Solution

let input = ['A', 'B', 'C', 'A', 'D', 'B', 'B', 'A', 'D']

const findWinner = (arr) => {

  const reduced = arr.reduce((acc, value) => ({ ...acc,
    [value]: (acc[value] || 0) + 1
  }), {})
  let pickLargest = Object.entries(reduced)
  const winner = pickLargest.reduce((acc, [key, value]) => {
    if (value > acc.maxValue) {
      acc.maxValue = value
      acc.winner = key
    } else if (value == acc.maxValue) {
      if (arr.lastIndexOf(key) > arr.lastIndexOf(acc.winner)) {
        acc.winner = acc.winner
      } else {
        acc.winner = key
      }
    }
    return acc
  }, {
    maxValue: 0,
    winner: ''
  })

  return winner.winner
}

console.log(findWinner(input));

Is there any other elegant way to achieve the same result?

Asraf
  • 1,322
  • 2
  • 12
Deepika Deepi
  • 127
  • 1
  • 8
  • @NinaScholz Then the item which reaches the max count first should be the output. – Deepika Deepi Nov 04 '22 at 19:08
  • Is the question for arbitrary element types or for single letters ? –  Nov 04 '22 at 19:21
  • @YvesDaoust It must be for arbitrary element types. Just for ease of convenience, I modified into string. – Deepika Deepi Nov 04 '22 at 19:23
  • 1
    A straightforward solution is to enter all elements in a dictionary, with a counter of occurrences and the index of the last occurrence. Then enumerate all entries and find the higest count/lowest index. –  Nov 04 '22 at 19:27

2 Answers2

2

You could take an object for keeping track of the counts and adjust max, if necessary.

const
    findWinner = array => {
        const counts = {};
        let max;
        
        for (const value of array) {
            counts[value] = (counts[value] || 0) + 1;
            if (counts[value] <= counts[max]) continue;
            max = value;
        }

        return max;
    };

console.log(findWinner(['A', 'B', 'C', 'A', 'D', 'B', 'B', 'A', 'D']));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

This should work:

const findWinner = ary => {
  const occurrences = Object.fromEntries(ary.map(e => [e, 0]));
  for(let el of ary){
    occurrences[el]++
  }
  let sorted = Object.entries(occurrences).sort((a, b) => a[1] > b[1]);

  return sorted[0][0];
}
Dr. Vortex
  • 505
  • 1
  • 3
  • 16