1

Given an array of words, write a function that returns an array of the words that occur an even number of times.

function even(["hello", "hi", "hello", "elephant", "hi"]);

That output should be:

["hello", "hi"]

This has been a toy problem I have been struggling with recently. I have solved similar problems counting and returning the number of occurrences of elements in an array but am having trouble taking that logic and applying it to this problem.

This is what I have tried so far, but have hit a wall when trying to output just the even occurrences:

function even(collection) {
  var results = [];
  for(var i = 0; i < collection.length; i++){
    var value = collection[i];
    if(results[value]){
      results[value] = results[value] + 1;
  }else{
   results[value] = 1; 
  }
}
        return results;
}
Tyler P.
  • 21
  • 3
  • 1
    Possible duplicate of [Easiest way to find duplicate values in a JavaScript array](http://stackoverflow.com/questions/840781/easiest-way-to-find-duplicate-values-in-a-javascript-array) – Zakaria Acharki Jul 08 '16 at 15:23
  • I mis-read and answered, but before I could edit to add the correct answer, @tymeJV posted a correct answer. Mine has been deleted. – Jacques ジャック Jul 08 '16 at 15:37

5 Answers5

2

You can use reduce to get an actual count of the words, then simply return an array of the ones that have an even count:

function even(wordsArr) {
    //Object of words and counts
    var wordCounts = wordsArr.reduce(function(counts, word) {
        if (!counts.hasOwnProperty(word)) {
            counts[word] = 0;
        }

        counts[word]++;
        return counts;
    }, {});

    //Now filter that out and return
    return Object.keys(wordCounts).filter(function(word) {
        return wordCounts[word] % 2 === 0
    });
}

even(["hello", "hi", "hello", "elephant", "hi"]); //["hello", "hi"]
tymeJV
  • 103,943
  • 14
  • 161
  • 157
0

var arr = ["hello", "hi", "hello", "elephant", "hi"];


function onlyEvens( arr )
{
  var countObj = {};
  for( var i = 0; i < arr.length; i++ )
  {
    var item = arr[i];
    
    if( countObj[ item ] !== undefined )
      countObj[item]++;
    else
      countObj[item] = 1;
  }//for()
  
  var filteredArray = [];
  
  for(var key in countObj )
  {
    if( countObj[key] % 2 == 0 )
      filteredArray.push( key );
  }
  
  return filteredArray;
}//onlyEvens()

console.log( onlyEvens( arr ) );
Mohit Bhardwaj
  • 9,650
  • 3
  • 37
  • 64
0

Issues in your code:

  • you use collection instead of words
  • you cannot access array the associative way. You must declare it as object:

    results[value]

  • you return result variable, but it is undeclared.

    return result;

  • results only contains the occurrences of every word. There miss the code that calculates if the occurrences of a word are odd or even.

fixed code:

function even(words) {       // <<< in your code was collection
  var results = {};
  for(var i = 0; i < words.length; i++){
    var value = words[i];
    if(results[value]){
      results[value] = results[value] + 1;
    }else{
      results[value] = 1; 
    }
  }
  var ret = [];
  for(var word in results)
    if(results[word]%2 !== 0)
      rest.push(word);

  return ret;
}
morels
  • 2,095
  • 17
  • 24
0

function even(list) {
  var d = list.reduce(function(d, w) { d[w] = !d[w]; return d; }, {});
  return Object.keys(d).filter(function(w) { return !d[w]; });
}

console.log(even(["hello", "hi", "hello", "elephant", "hi"]));
console.log(even(["hello", "yo", "yo", "hi", "hello", "yo", "elephant", "hi"]));

Explanation: Use the array .reduce() method to create an object (d) with a property for each word (w) with a boolean value indicating whether the word has an odd number of occurrences. Then .filter() the keys to get all the ones that are not odd.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
0

If you previously sort the array you can filter it as required in just a code line like this :

var even = (str) => str.sort().filter((element, index, arr) => index+1 === arr.lastIndexOf(element));

console.log(even(["hello", "hello", "hi", "elephant", "hi", "hi"])); //[ 'hello', 'hi' ]
kevin ternet
  • 4,514
  • 2
  • 19
  • 27