【问题标题】:JavaScript Object as counter not incrementingJavaScript对象作为计数器不递增
【发布时间】:2018-10-27 22:23:53
【问题描述】:

我正在尝试使用对象作为 JavaScript 中的计数器,以查找单词中重复次数最多的字母,但不知何故,该函数无法按我的预期工作。例如,当我调用findMaxRepeatCountInWord('expected') 时,letterCount 对象的值最终为{ e: 1, x: 1, p: 1, c: 1, t: 1, d: 1 }。我的代码有什么问题? e 的值不应该是 3 吗?

我的代码:

function findMaxRepeatCountInWord(word){
  var letterCount = {};
  word.split('').map(function(v){
    if(letterCount[v] != true){ letterCount[v] = 1 } 
    else(letterCount[v] ++)
  });
  return Object.values(letterCount).sort((a,b) => b-a)[0]
}

findMaxRepeatCountInWord('expected')

【问题讨论】:

  • 不是....我尝试将 else{} 语句中的条件更改为 'console.log(v)' 并且效果很好 - 它会打印出两次 'e'。所以这个函数肯定飞到了 else{} 语句中,我只是不明白为什么里面的动作没有实现。
  • 但是有三个es。它计数 1, 2, 1

标签: javascript object counter


【解决方案1】:

这不会像你希望的那样工作:

 if(letterCount[v] != true)

尝试使用 !hasOwnProperty 进行测试(并使用 forEach 代替 map):

function findMaxRepeatCountInWord(word){
    var letterCount = {};
    word.split('').forEach(function(v){
      if(!letterCount.hasOwnProperty(v)){ letterCount[v] = 1 } 
      else letterCount[v] ++
    });
    console.log("letter counts", letterCount)
    return Object.values(letterCount).sort((a,b) => b-a)[0]
  }
  
  console.log(findMaxRepeatCountInWord('expected'))
  

您还可以通过以下方式节省排序成本:

return Math.max(...Object.values(letterCount))

【讨论】:

  • 并非总是...仅适用于 1
  • 感谢您的建议,我认为Math.max 函数不适用于数字数组,不是吗?
  • @rhea.rao 确实如此
  • @rhea.rao Object.values(letterCount) 返回一个数组或数字,该数组或数字传播到Math.max
  • Math.max(1,2,3) 将返回 3,但 Math.max([1,2,3]) 将返回 NaN
【解决方案2】:

那是另一种版本的JS比较好玩:

 console.log(
   0 != true, // true
   1 != true, // false
   2 != true // true
   3 != true // true
);

如果你比较一个数字和一个布尔值,布尔值会变成一个数字(0 -> false,1 -> true)然后进行相等比较,因此只有1等于true。 因此如果到达2,它会再次进入第一个分支并将计数器重置为1

【讨论】:

    【解决方案3】:

    您需要按以下方式检查属性:if (v in letterCount) 这是检查键是否是对象的属性的最可靠方法。

    这种方法返回构建的对象

    function findMaxRepeatCountInWord(word) {
      var letterCount = {};
      word.split('').map(function(v) {
        letterCount[v] = (letterCount[v] || 0) + 1;
      });
      
      return letterCount;
    }
    
    console.log(findMaxRepeatCountInWord('expected'))
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    顺便说一句,使用函数Array.prototype.map 并不是解决此问题的最佳方法,因为您正在创建一个不必要的数组。

    使用函数Array.prototype.reduce 对字母进行分组的替代方法

    function findMaxRepeatCountInWord(word) {
      return word.split('').reduce((a, c) => {
        a[c] = (a[c] || 0) + 1;
        return a;
      }, Object.create(null));
    }
    
    console.log(findMaxRepeatCountInWord('expected'))
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案4】:

      您的代码是正确的,除了 if 条件: if(letterCount[v] != true).

      解决办法: 您只需将条件更改为以下内容即可轻松解决问题: if(letterCount[v] == undefined)

      问题: 在以下情况下,条件会按您的预期工作:

      • letterCount[v]undefined
      • letterCount[v]1

      但是当letterCount[v]大于1时,条件又为真,因为2 != truetrue。因此,每次遇到奇数次时,您的代码都会将值重置为 1

      为了说明,如果我们在一个只有两个 e 的单词上运行您的代码,我们会得到:

      findMaxRepeatCountInWord('expectd')
      > 2
      

      但如果第三次出现该字母,如您的示例,则该数字将重置为1

      性能 然而,这种方法在计算上不是很有效。对于有关类似问题的有效解决方案的一些讨论,您可能想要给出例如this question 看看。

      【讨论】:

        【解决方案5】:
        function findMaxRepeatCountInWord(word){
          var letterCount = {};
          word.split('').map(function(v){
            if(letterCount[v]==undefined){ letterCount[v]= 1 ;
        } 
            else{letterCount[v]=letterCount[v]+1}
          });
          return Object.values(letterCount).sort((a,b) => b-a)[0]
        }
        
        var x=findMaxRepeatCountInWord('expected');
        console.log(x);
        

        【讨论】:

          【解决方案6】:

          if 应该是:

          if(!letterCount[v]){ letterCount[v] = 1 } 
          else {letterCount[v]++}
          

          保持对代码的修改最少。其他答案更完善。


          应用于OP代码:

          function findMaxRepeatCountInWord(word){
            var letterCount = {};
            word.split('').map(function(v){
              if(!letterCount[v]){ letterCount[v] = 1 } 
              else(letterCount[v] ++)
            });
            console.log(letterCount)
            return Object.values(letterCount).sort((a,b) => b-a)[0]
          }
          
          findMaxRepeatCountInWord('super expected');

          【讨论】:

          • {} 用于if/else 不是强制性的,尽管这是最佳做法
          • 对,但是原代码用括号代替了括号,这也很重要。
          • 不是真的...丑陋但有效
          • 嗯,你是对的。像表达式分组一样工作?主要问题确实是if
          • 对不起,这不正确,0 == false,1 == true,2 == false,所以当我们数到 2 时,letterCount[v] 将再次被赋值为 1,请参阅以上答案
          猜你喜欢
          • 1970-01-01
          • 2016-02-03
          • 1970-01-01
          • 2023-04-10
          • 1970-01-01
          • 2022-01-18
          • 1970-01-01
          • 1970-01-01
          • 2012-09-05
          相关资源
          最近更新 更多