如何使用reduce方法返回一个对象,该对象跟踪数组中特定字符的实例?

问题描述

const array = ['w','h','a','t',' ','i','s','a'];

让我们跟踪一下字母的实例:a,s,p,y, 如何使用reduce方法返回以下对象

{a:2,s:1,p:0,y:0}

解决方法

尝试!

const array = ["w","h","a","t","i","s","a"];

const letters = {
  a:0,s:0,p:0,y:0
};

const result = array.reduce((prev,curr) => {
  if(prev.hasOwnProperty(curr)) prev[curr]++;
  return prev;
},letters);

console.log(result) // {a:2,s:1,y:0}

reduce函数总共需要2个参数,并且可以将第二个参数用作初始值。

第一个参数是回调函数,需要4个参数。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

,

您可以通过频率计数来解决它。

const array = ["w"," ","a"];

let ret = array.reduce(
  (p,c) => {
    if (c === "a" || c === "s" || c === "p" || c === "y") {
      p[c]++;
    }
    return p;
  },{ a: 0,s: 0,p: 0,y: 0 }
);
console.log(ret);

,

这里已经有一些不错的答案,但这是另一种观点。 reduce方法允许我们根据对两个基本问题的答案来表达对数组的计算。 如果我们对这些问题的回答充满信心,那么我们可以对整个过程本身充满信心。 这就是reduce真正闪耀的地方。 因此,尽管可以在传递给reduce的函数中对值进行突变,但这会抵消这一好处。 考虑到这一点,这是一个避免变异的选项,目的是突出强调reduce的这种灌输信心的方法。

如果我们将所需的计算框架为一个问题,关键是要回答以下两个问题:

  1. 一个空数组的答案是什么?

  2. 给出一个数组的答案和一个附加元素,增强数组的答案是什么?

让我们一次看看这些。 在我们的案例中,问题是:“如何计算数组中字符的频率?”

  1. 给出一个空数组,没有要考虑的字符,因此没有要报告的频率。 因此,这里的答案就是{}

现在问问题2。 假设我们已经计算了chars数组中所有字符的频率。 我们将此部分答案称为freqs。 也就是说,freqs是一些可以正确描述chars数组中字符频率的对象。

现在我们有了一个新字符(我们称其为c),我们需要计算一个更新的频率集合,以说明c的存在。 好吧,大多数频率都将保持不变,因此这是一个好的开始:

newFreqs = { ...freqs }

...但这不是全部。 我们还需要考虑新的字符c。 有两种情况需要考虑:要么我们以前已经看到过此字符(在这种情况下,我们的freqs对象中已经有一个条目),要么这是我们第一次看到它。 在第一种情况下,我们需要增加与freqs中的字符关联的值,在第二种情况下,频率就是1(因为这是我们第一次遇到该字符。 可能看起来像这样:

newFreqs = {
  // Keep everything the way it is
  ...freqs,// except for `c`'s entry,which needs to be incremented or set to 1
  [c]: (freqs[c] || 0) + 1
}

现在我们已经回答了这两个问题,剩下的只是安排问题:

function charFreqs(chars) {
  return chars.reduce((freqs,c) => ({
    ...freqs,[c]: (freqs[c] || 0) + 1,}),{});
}

有关演示,请参见here

不请自来的广告:reduce方法将列表中的归纳属性进行编码,这就是为什么它如此强大(当不经突变使用时)的原因。 我们一直在试图(有意识地或无意识地)证明我们编写的功能正确运行,而归纳法是这方面最好的工具之一。