简体   繁体   English

使用reduce和map获取数组中对象的频率

[英]Get frequencies of objects in an array using reduce and map

I'm trying to write a function which will take in an array and then return a map of the frequencies of each object in the array. 我正在尝试编写一个将接收数组的函数,然后返回数组中每个对象的频率的映射。 For example, for the following array: 例如,对于以下数组:

freqs([1, 2, 3, 7, 2, 7, 1, 2, 1]) 

it will return a map like the following: 它将返回如下地图:

Map {1 => 3, 2 => 3, 3 => 1, 7 => 2}

Here is what I have so far: 这是我到目前为止的内容:

function freqs(items) {
    return items.reduce(function(prev, curr)
    {
        if (curr in prev)
        {
            prev[curr]++;
        }
        else
        {
            prev[curr]=1;
        }

        return prev.map();
    });

}

However, when I try to test it, I get the following error: 但是,当我尝试对其进行测试时,出现以下错误:

Uncaught TypeError: Cannot use 'in' operator to search for '1' in 1 Uncaught TypeError:无法使用'in'运算符在1中搜索'1'

What is causing this? 是什么原因造成的? Also, is my logic correct? 另外,我的逻辑正确吗? I feel like I'm doing something wrong. 我觉得我做错了什么。

  1. If you don't provide an initial value to reduce , it will by default use the first element as the initial value. 如果您没有提供reduce的初始值,则默认情况下它将使用第一个元素作为初始值。 In your case, prev becomes 1 . 就您而言, prev变为1 Thats why you are getting this error. 那就是为什么您收到此错误。 You should set the initial value to a Map object. 您应该将初始值设置为Map对象。

  2. prev.map() - I have no clue what the intention is prev.map() -我不知道意图是什么

  3. When you do prev[curr] , you are using the prev as a normal JavaScript object. 当您执行prev[curr] ,您prev[curr] prev用作普通的JavaScript对象。 Maps don't have bracket notation to access their values. Maps没有方括号符号来访问其值。


Your fixed program would look like this 您的固定程序如下所示

function freqs(items) {
  return items.reduce(function(prev, c) {
    if (prev.has(c)) {  // use `has` and `set` operations on Map objects
      prev.set(c, prev.get(c) + 1);
    } else {
      prev.set(c, 1);
    }
    return prev;    // return the map, so it will be prev for the next iteration
  }, new Map());    // Set the initial value to a new Map object
}

console.log(freqs([1, 2, 3, 7, 2, 7, 1, 2, 1]));
// Map { 1 => 3, 2 => 3, 3 => 1, 7 => 2 }

You are inconsistantly using c vs curr and p vs prev . 您使用c vs currp vs prev不一致。 You are using map the wrong way. 您使用地图的方式错误。
Instead, just return prev; 相反,只return prev;
Next up, you need to set a initial value for the prev -variable. 接下来,您需要为prev -variable设置初始值。 This should be an empty object {} as a second argument for reduce . 这应该是一个空对象{}作为reduce的第二个参数。 Do this, and you should be fine. 这样做,你应该没事。

function freqs(items) {
    return items.reduce(function(prev, curr)
    {
        if (curr in prev)
        {
            prev[curr]++;
        }
        else
        {
            prev[curr]=1;
        }

        return prev;
    },{});

}

You can use Array.prototype.reduce() to set property of object to value of array element, increment value for each matched element; 您可以使用Array.prototype.reduce()将对象的属性设置为数组元素的值,为每个匹配的元素增加值; Object.keys() , Array.prototype.forEach() to set value of Map Object.keys()Array.prototype.forEach()设置Map

 var freq = (arr) => { var map = new Map(); var obj = {}; Object.keys(arr.reduce((obj, prop) => { return (prop in obj ? ++obj[prop] : (obj[prop] = 1)), obj }, obj)).forEach(el => map.set(el, obj[el])); return map }; var arr = [1, 2, 3, 7, 2, 7, 1, 2, 1]; console.log(freq(arr)); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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