Counting the occurrences / frequency of array elements

前端 未结 30 2098
甜味超标
甜味超标 2020-11-21 06:47

In Javascript, I\'m trying to take an initial array of number values and count the elements inside it. Ideally, the result would be two new arrays, the first specifying each

30条回答
  •  失恋的感觉
    2020-11-21 07:18

    Edit 2020: this is a pretty old answer (nine years). Extending the native prototype will always generate discussion. Although I think the programmer is free to choose her own programming style, here's a (more modern) approach to the problem without extending Array.prototype:

    {
      // create array with some pseudo random values (1 - 5)
      const arr = Array.from({length: 100})
        .map( () => Math.floor(1 + Math.random() * 5) );
      // frequencies using a reducer
      const arrFrequencies = arr.reduce((acc, value) => 
          ({ ...acc, [value]: acc[value] + 1 || 1}), {} )
      console.log(`Value 4 occurs ${arrFrequencies[4]} times in arrFrequencies`);
    
      // bonus: restore Array from frequencies
      const arrRestored = Object.entries(arrFrequencies)
        .reduce( (acc, [key, value]) => acc.concat(Array(value).fill(+key)), [] );
      console.log(arrRestored.join());  
    }
    .as-console-wrapper { top: 0; max-height: 100% !important; }

    The old (2011) answer: you could extend Array.prototype, like this:

    {
      Array.prototype.frequencies = function() {
        var l = this.length,
          result = {
            all: []
          };
        while (l--) {
          result[this[l]] = result[this[l]] ? ++result[this[l]] : 1;
        }
        // all pairs (label, frequencies) to an array of arrays(2)
        for (var l in result) {
          if (result.hasOwnProperty(l) && l !== 'all') {
            result.all.push([l, result[l]]);
          }
        }
        return result;
      };
    
      var freqs = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].frequencies();
      console.log(`freqs[2]: ${freqs[2]}`); //=> 5
      
      // or
      var freqs = '1,1,2,one,one,2,2,22,three,four,five,three,three,five'
        .split(',')
        .frequencies();
        
      console.log(`freqs.three: ${freqs.three}`); //=> 3
      
    // Alternatively you can utilize Array.map:
    
        Array.prototype.frequencies = function() {
          var freqs = {
            sum: 0
          };
          this.map(function(a) {
            if (!(a in this)) {
              this[a] = 1;
            } else {
              this[a] += 1;
            }
            this.sum += 1;
            return a;
          }, freqs);
          return freqs;
        }
    }
    .as-console-wrapper { top: 0; max-height: 100% !important; }

提交回复
热议问题