user7313850
user7313850

Reputation:

Get the number of times each string occurs in an Array

function countWords(inputWords) {
var sortArray = inputWords.sort(function (idx1, idx2) { return idx1.localeCompare(idx2) });
var resultArray = [];
var counter = 1;

sortArray.reduce(function (total, currentValue) {
    if (total == currentValue)
        counter++;
    else {
        resultArray.push(counter);
        counter = 1;
    }
    return currentValue;
});

    return resultArray;
}
module.exports = countWords

So currently I'm trying to get the number of times each string occurs in an Array. I wrote the function above, but it seems that it has a bug.

PS: That is an exercise of https://nodeschool.io/ .. npm install -g functional-javascript-workshop . I have to use the reduce function and I'm not allowed to use any for/while loops

That was my input/output:

input:      [ 'ad', 'ad', 'ad', 'aliqua', 'aliquip', 'aute', 'consectetur', 'consequat', 'culpa', 'culpa', 'culpa', 'do', 'do', 'dolor', 'dolore', 'eiusmod', 'elit', 'esse', 'esse', 'est', 'et', 'et', 'ex', 'excepteur', 'excepteur', 'exercitation', 'exercitation', 'id', 'id', 'id', 'incididunt', 'labore', 'laborum', 'lorem', 'magna', 'minim', 'minim', 'minim', 'mollit', 'nostrud', 'nulla', 'pariatur', 'proident', 'qui', 'qui', 'reprehenderit', 'reprehenderit', 'sint', 'ullamco', 'velit' ]
submission: [ 3, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 2, 1, 2, 1, 2, 2, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 2, 2, 1, 1 ]

The workshop "says" that this is wrong.

Can somebody help?

Upvotes: 1

Views: 106

Answers (1)

Ori Drori
Ori Drori

Reputation: 191986

The workshop check probably has a problem with the order of the results you submitted, because of the Array#sort you use at the start of the function.

You can use these methods to count without changing the order of the results:

A ES6 word counter with Array#reduce that uses array spread syntax and Map. The Map counts the words. The Map is converted to an iterator by the Map#values, and then to an array using spread.

const words = [ 'ad', 'ad', 'ad', 'aliqua', 'aliquip', 'aute', 'consectetur', 'consequat', 'culpa', 'culpa', 'culpa', 'do', 'do', 'dolor', 'dolore', 'eiusmod', 'elit', 'esse', 'esse', 'est', 'et', 'et', 'ex', 'excepteur', 'excepteur', 'exercitation', 'exercitation', 'id', 'id', 'id', 'incididunt', 'labore', 'laborum', 'lorem', 'magna', 'minim', 'minim', 'minim', 'mollit', 'nostrud', 'nulla', 'pariatur', 'proident', 'qui', 'qui', 'reprehenderit', 'reprehenderit', 'sint', 'ullamco', 'velit' ];

const countWords = (words) => [...words.reduce((m, w) => m.set(w, (m.get(w) || 0) + 1), new Map).values()];

const result = countWords(words);

console.log(result);

And the ES5 version that uses Array#reduce with a hash object.

var words = [ 'ad', 'ad', 'ad', 'aliqua', 'aliquip', 'aute', 'consectetur', 'consequat', 'culpa', 'culpa', 'culpa', 'do', 'do', 'dolor', 'dolore', 'eiusmod', 'elit', 'esse', 'esse', 'est', 'et', 'et', 'ex', 'excepteur', 'excepteur', 'exercitation', 'exercitation', 'id', 'id', 'id', 'incididunt', 'labore', 'laborum', 'lorem', 'magna', 'minim', 'minim', 'minim', 'mollit', 'nostrud', 'nulla', 'pariatur', 'proident', 'qui', 'qui', 'reprehenderit', 'reprehenderit', 'sint', 'ullamco', 'velit' ];

function countWords(arr) {
  return words.reduce(function(m, w) {
    // if the hash doesn't include the word
    if (!m.hash.hasOwnProperty(w)) {
      // push a new count of 0 to that word
      m.counts.push(0)
      
      // add the index of the word's count
      m.hash[w] = m.counts.length - 1;
    }

    // increment the count at the index of the word's count
    m.counts[m.hash[w]]++;

    return m;
  }, { hash: {}, counts: [] }).counts; // return the counts array
}

var result = countWords(words);

console.log(result);

Upvotes: 1

Related Questions