Counting the occurrences / frequency of array elements

前端 未结 30 2169
甜味超标
甜味超标 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:33

    Using MAP you can have 2 arrays in the output: One containing the occurrences & the other one is containing the number of occurrences.

    const dataset = [2,2,4,2,6,4,7,8,5,6,7,10,10,10,15];
    let values = [];
    let keys = [];
    
    var mapWithOccurences = dataset.reduce((a,c) => {
      if(a.has(c)) a.set(c,a.get(c)+1);
      else a.set(c,1);
      return a;
    }, new Map())
    .forEach((value, key, map) => {
      keys.push(key);
      values.push(value);
    });
    
    
    console.log(keys)
    console.log(values)

    0 讨论(0)
  • 2020-11-21 07:34

    Here's just something light and easy for the eyes...

    function count(a,i){
     var result = 0;
     for(var o in a)
      if(a[o] == i)
       result++;
     return result;
    }
    

    Edit: And since you want all the occurences...

    function count(a){
     var result = {};
     for(var i in a){
      if(result[a[i]] == undefined) result[a[i]] = 0;
      result[a[i]]++;
     }
     return result;
    }
    
    0 讨论(0)
  • 2020-11-21 07:35
    var array = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
    
    function countDuplicates(obj, num){
      obj[num] = (++obj[num] || 1);
      return obj;
    }
    
    var answer = array.reduce(countDuplicates, {});
    // answer => {2:5, 4:1, 5:3, 9:1};
    

    If you still want two arrays, then you could use answer like this...

    var uniqueNums = Object.keys(answer);
    // uniqueNums => ["2", "4", "5", "9"];
    
    var countOfNums = Object.keys(answer).map(key => answer[key]);
    // countOfNums => [5, 1, 3, 1];
    

    Or if you want uniqueNums to be numbers

    var uniqueNums = Object.keys(answer).map(key => +key);
    // uniqueNums => [2, 4, 5, 9];
    
    0 讨论(0)
  • 2020-11-21 07:35

    My solution with ramda:

    const testArray = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]
    
    const counfFrequency = R.compose(
      R.map(R.length),
      R.groupBy(R.identity),
    )
    
    counfFrequency(testArray)
    

    Link to REPL.

    0 讨论(0)
  • 2020-11-21 07:36

    Don't use two arrays for the result, use an object:

    a      = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
    result = { };
    for(var i = 0; i < a.length; ++i) {
        if(!result[a[i]])
            result[a[i]] = 0;
        ++result[a[i]];
    }
    

    Then result will look like:

    {
        2: 5,
        4: 1,
        5: 3,
        9: 1
    }
    
    0 讨论(0)
  • 2020-11-21 07:36

    How about an ECMAScript2015 option.

    const a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
    
    const aCount = new Map([...new Set(a)].map(
        x => [x, a.filter(y => y === x).length]
    ));
    
    aCount.get(5)  // 3
    aCount.get(2)  // 5
    aCount.get(9)  // 1
    aCount.get(4)  // 1
    

    This example passes the input array to the Set constructor creating a collection of unique values. The spread syntax then expands these values into a new array so we can call map and translate this into a two-dimensional array of [value, count] pairs - i.e. the following structure:

    Array [
       [5, 3],
       [2, 5],
       [9, 1],
       [4, 1]
    ]
    

    The new array is then passed to the Map constructor resulting in an iterable object:

    Map {
        5 => 3,
        2 => 5,
        9 => 1,
        4 => 1
    }
    

    The great thing about a Map object is that it preserves data-types - that is to say aCount.get(5) will return 3 but aCount.get("5") will return undefined. It also allows for any value / type to act as a key meaning this solution will also work with an array of objects.

    function frequencies(/* {Array} */ a){
        return new Map([...new Set(a)].map(
            x => [x, a.filter(y => y === x).length]
        ));
    }
    
    let foo = { value: 'foo' },
        bar = { value: 'bar' },
        baz = { value: 'baz' };
    
    let aNumbers = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
        aObjects = [foo, bar, foo, foo, baz, bar];
    
    frequencies(aNumbers).forEach((val, key) => console.log(key + ': ' + val));
    frequencies(aObjects).forEach((val, key) => console.log(key.value + ': ' + val));

    0 讨论(0)
提交回复
热议问题