Counting the occurrences / frequency of array elements

前端 未结 30 2104
甜味超标
甜味超标 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: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));

提交回复
热议问题