简体   繁体   中英

Find the Words with an even number of occurrences in an Array - Javascript

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;
}

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"]

 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 ) ); 

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;
}

 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.

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' ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM