Is there a Javascript function similar to the Python Counter function?

前端 未结 6 2221
逝去的感伤
逝去的感伤 2021-02-19 01:17

I am attempting to change a program of mine from Python to Javascript and I was wondering if there was a JS function like the Counter function from the collections module in Pyt

相关标签:
6条回答
  • 2021-02-19 02:03

    For those who want a pure JavaScript solution:

    function countBy (data, keyGetter) {
      var keyResolver = {
        'function': function (d) { return keyGetter(d); },
        'string': function(d) { return d[keyGetter]; },
        'undefined': function (d) { return d; }
      };
    
      var result = {};
    
      data.forEach(function (d) {
        var keyGetterType = typeof keyGetter;
        var key = keyResolver[keyGetterType](d);
    
        if (result.hasOwnProperty(key)) {
          result[key] += 1;
        } else {
          result[key] = 1;
        }
      });
    
      return result;
    }
    

    Therefore:

    list1 = ['a', 'b', 'c', 'b', 'a', 'b', 'c', 'a', 'a', 'a'];
    console.log(countBy(list1));  // {'a':5, 'b':3, 'c':2}
    
    list2 = ['abc', 'aa', 'b3', 'abcd', 'cd'];
    console.log(countBy(list2, 'length'));  // {2: 3, 3: 1, 4: 1}
    
    list3 = [1.2, 7.8, 1.9];
    console.log(countBy(list3, Math.floor));  // {1: 2, 7: 1}
    
    0 讨论(0)
  • 2021-02-19 02:04

    DIY JavaScript solution:

    var list = ['a', 'b', 'c', 'b', 'a', 'b', 'c', 'a', 'a', 'a'];
    
    function Counter(array) {
      var count = {};
      array.forEach(val => count[val] = (count[val] || 0) + 1);
      return count;
    }
    
    console.log(Counter(list));
    

    JSFiddle example

    Update:

    Alternative that uses a constructor function:

    var list = ['a', 'b', 'c', 'b', 'a', 'b', 'c', 'a', 'a', 'a'];
    
    function Counter(array) {
      array.forEach(val => this[val] = (this[val] || 0) + 1);
    }
    
    console.log(new Counter(list));
    

    JSFiddle example

    0 讨论(0)
  • 2021-02-19 02:04

    I know I'm late but in case if someone is looking at this in 2020 you can do it using reduce, for example:

    const counter = (list) => {
      return list.reduce(
        (prev, curr) => ({
          ...prev,
          [curr]: 1 + (prev[curr] || 0),
        }),
        {}
      );
    };
    
    console.log(counter([1, 2, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 1, 0]));
    // output -> { '0': 1, '1': 6, '2': 2, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1 }
    

    more advance example with a callback function and context binding

    const data = [1, 2, 3, 4, 5];
    
    const counter = (list, fun, context) => {
      fun = context ? fun.bind(context) : fun;
      return list.reduce((prev, curr) => {
        const key = fun(curr);
        return {
          ...prev,
          [key]: 1 + (prev[key] || 0),
        };
      }, {});
    };
    
    
    console.log(counter(data, (num) => (num % 2 == 0 ? 'even' : 'odd')));
    // output -> { odd: 3, even: 2 }
    
    0 讨论(0)
  • 2021-02-19 02:13

    You can use Lo-Dash's countBy function:

    var list = ['a', 'b', 'c', 'b', 'a', 'b', 'c', 'a', 'a', 'a'];
    console.log(_.countBy(list));
    

    JSFiddle example

    0 讨论(0)
  • 2021-02-19 02:14

    There is also pycollections.js, which works on Node and in client-side JS.

    Example:

    var collections = require('pycollections');
    var counter = new collections.Counter([true, true, 'true', 1, 1, 1]);
    counter.mostCommon(); // logs [[1, 3], [true, 2], ['true', 1]] 
    
    0 讨论(0)
  • 2021-02-19 02:18

    Here is a simple and easy to read solution:

     const word1 = "tangram"
        const dict1 = {}
        for (let char of word1){
         console.log(char)
         if (dict1[char]){
           dict1[char] += 1
           }else{
         dict1[char]= 1
         }
        }

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