infodev
infodev

Reputation: 5235

Count string occurence in array using only reduce does not read last value

I would make a program usin reduce that counts number of occurence of a string in an array.

I should only use reduces.

Here's my program.

function countWords(inputWords) {
  let obj={};
  inputWords.reduce((curr,next )=> {
     obj[curr]=0;
    inputWords.reduce((current,next2)=> {
      if(curr===current) {
        obj[curr]++;
      }
      return next2
    });
    return next;
  })
  return obj
}

What my result prints

My result : { exercitation: 1, non: 1, irure: 1, commodo: 3, velit: 2, officia: 1, consectetur: 4, laboris: 2, est: 2, aliquip: 1, excepteur: 1, consequat: 1, magna: 1, id: 1, eiusmod: 1, veniam: 1, anim: 1, ullamco: 1, elit: 2, nulla: 1, cupidatat: 2, proident: 1, lorem: 1, ad: 1, quis: 1, dolore: 1, occaecat: 1, aliqua: 1, tempor: 1, do: 1, dolor: 1, labore: 1 }

What is expected:

Expected result : { exercitation: 1, non: 1, irure: 1, commodo: 3, velit: 2, officia: 1, consectetur: 4, laboris: 2, est: 2, aliquip: 1, excepteur: 1, consequat: 1, magna: 1, id: 1, eiusmod: 1, veniam: 1, anim: 1, ullamco: 1, elit: 2, nulla: 1, cupidatat: 2, proident: 1, lorem: 1, ad: 1, quis: 1, dolore: 1, occaecat: 1, aliqua: 1, tempor: 1, do: 1, dolor: 1, labore: 1, amet: 1 }

Here's the inputs words:

Input:[ 'exercitation', 'non', 'irure', 'commodo', 'velit', 'officia', 'consectetur', 'commodo', 'laboris', 'est', 'aliquip', 'excepteur', 'consequat', 'consectetur', 'magna', 'id', 'eiusmod', 'veniam', 'anim', 'consectetur', 'ullamco', 'elit', 'nulla', 'cupidatat', 'proident', 'commodo', 'laboris', 'est', 'lorem', 'consectetur', 'elit', 'ad', 'quis', 'dolore', 'occaecat', 'aliqua', 'cupidatat', 'tempor', 'do', 'dolor', 'velit', 'labore', 'amet' ]

Upvotes: 0

Views: 46

Answers (2)

KooiInc
KooiInc

Reputation: 122936

You should always return the object containing frequencies within the reducer. The initial object can be the second parameter of Array.reduce.

So, here's a oneliner for you:

(() => {
  const input = ['exercitation', 'non', 'irure', 'commodo', 'velit', 'officia', 
    'consectetur', 'commodo', 'laboris', 'est', 'aliquip', 'excepteur', 'consequat', 
    'consectetur', 'magna', 'id', 'eiusmod', 'veniam', 'anim', 'consectetur', 
    'ullamco', 'elit', 'nulla', 'cupidatat', 'proident', 'commodo', 'laboris', 'est', 
    'lorem', 'consectetur', 'elit', 'ad', 'quis', 'dolore', 'occaecat', 'aliqua', 
    'cupidatat', 'tempor', 'do', 'dolor', 'velit', 'labore', 'amet'];
  console.log(input.reduce( (f, v) => v in f ? (f[v] += 1, f) : (f[v] = 1, f), {}));
  /* which can also be written as:
    input.reduce( (frequencies, value) => {
      if (frequencies[value]) {
        // frequencies contains the value key, so increment
        frequencies[value] += 1;
      } else {
        // add value to frequencies and initialize ([value] = 1)
        frequencies[value] = 1;
      }
      // return the now updated frequencies object for further use
      return frequencies;
    }, {});
    // ^ the initial frequencies object
  */
})();

Upvotes: 1

brk
brk

Reputation: 50326

There may not be an requirement of using a reduce inside another reduce method. In the object check if the key exist or not, if not then create the key in the object otherwise update it's value by 1

let input = ['exercitation', 'non', 'irure', 'commodo', 'velit', 'officia', 'consectetur', 'commodo', 'laboris', 'est', 'aliquip', 'excepteur', 'consequat', 'consectetur', 'magna', 'id', 'eiusmod', 'veniam', 'anim', 'consectetur', 'ullamco', 'elit', 'nulla', 'cupidatat', 'proident', 'commodo', 'laboris', 'est', 'lorem', 'consectetur', 'elit', 'ad', 'quis', 'dolore', 'occaecat', 'aliqua', 'cupidatat', 'tempor', 'do', 'dolor', 'velit', 'labore', 'amet']

let result = input.reduce(function(acc, curr) {
  if (!acc.hasOwnProperty(curr)) {
    acc[curr] = 1;
  } else {
    acc[curr] += 1;
  }
  return acc;
}, {})
console.log(result)

Upvotes: 1

Related Questions