【问题标题】:Write a function which takes in a string and returns the counts of each string [duplicate]编写一个函数,该函数接受一个字符串并返回每个字符串的计数[重复]
【发布时间】:2019-07-26 18:00:19
【问题描述】:

我确实被困在解决这个简单的问题上。无论如何,我找到了另一种解决此问题的方法,但我无法找出我的代码的问题。

function charCout(str)
{
    str = str.toLowerCase();
    var f  = {};

    for(let i =0;i<str.length;i++)
    {
        if(str[i] === " ")
        {
            continue;
        }
        else{
            if(str[i] in Object.keys(f))
            {
                f[str[i]] += 1;
            }
            else
            {
                f[str[i]] = 1;
            }
        }
    }
  return(f);   
}




input: charCout("my name is Khan23")
expected output: {2: 1,3: 1,a: 2,e: 1,h: 1,i: 1,k: 1,m: 2,n: 2,s: 1,y: 1}
what i got: {2: NaN,3: NaN,a: 1,e: 1,h: 1,i: 1,k: 1,m: 1,n: 1,s: 1,y: 1}

【问题讨论】:

  • 您只需要str[i] in f,而不是str[i] in Object.keys(f)。如果您要获取所有键的数组,则需要执行 Object.keys(f).includes(str[i])(但这非常低效)。

标签: javascript


【解决方案1】:

只需通过类型强制查看属性是否存在,例如:if(f[str[i]])

function charCount(str)
{
    str = str.toLowerCase();
    var f  = {};

    for(let i =0;i<str.length;i++)
    {
        if(str[i] === " ")
        {
            continue;
        }
        else{
            if(f[str[i]])
            {
                f[str[i]] += 1;
            }
            else
            {
                f[str[i]] = 1;
            }
        }
    }
  return(f);   
}

console.log(charCount('the value is 0000'))

【讨论】:

  • 从技术上讲,这并不是对它存在的真正检查,但在这种情况下有效,因为值在确实存在时总是真实的
  • @charlietfl 谢谢。当str[i]为0时,我修改了条件来打补丁
  • @CharlieH || 0 在某种条件下没有任何意义
  • @Bergi 真的。我误解了。已编辑。
【解决方案2】:

您使用了错误的方式来检查键是否在对象中。

您可以使用 || 运算符将您的 if-else 收缩为单行。

f[str[i]] = f[str[i]] + 1 || 1 

它检查f[str[i]] 是否已经存在。如果str[i] 不是f 的键,那么f[str[i]] 将返回undefined,而undefined + 1 将是NaN

NaN 是一个虚假值,因此 NaN || 1 将评估为 1

如果f[str[i]] 存在,那么它将返回任何大于0 的数字,因此它将被设置为f[str[i]] + 1(加一)

function charCount(str)
{
    str = str.toLowerCase();
    var f  = {};

    for(let i =0;i<str.length;i++)
    {
        if(str[i] !== " ")
        {
            f[str[i]] = f[str[i]] + 1 || 1 
        }
    }
  return(f);   
}
console.log(charCount("my name is Khan23"))

说明:

您也可以使用reduce()

const charCount = str => str
                          .split(' ')
                          .join('')
                          .split('')
                          .reduce((ac,a) => 
                              (ac[a] = ac[a] + 1 || 1, ac), 
                          {})


console.log(charCount("my name is Khan23"))

【讨论】:

  • || 不检查密钥是否存在。如果你真的想这样做,请解释一下它是如何工作的。
  • @Bergi 我已经添加了解释。
  • 谢谢。不过,我认为f[str[i]] = (f[str[i]] || 0) + 1 更好理解。或者直接使用明确的(str[i] in f ? f[str[i]] : 0) + 1
  • 我做的和你做@maheer的方式完全一样。我对这种方法没有问题。我只是想弄清楚上面的代码有什么问题(我的代码)
【解决方案3】:

使用Object.keys(f).includes(str[i]) 代替str[i] in Object.keys(f) 是解决方案

in 运算符主要用于检查 Object 是否提供特定属性

inArray.prototype.includes 上的 Mozilla 文档会有所帮助。

按照你的功能变化会起作用

function charCout(str)
{
    str = str.toLowerCase();
    var f  = {};

    for(let i =0;i<str.length;i++)
    {
        if(str[i] === " ")
        {
            continue;
        }
        else{
            if(Object.keys(f).includes(str[i]))
            {
                f[str[i]] += 1;
            }
            else
            {
                f[str[i]] = 1;
            }
        }
    }
  return(f);   
}

【讨论】:

  • 泰阿布舍克。现在我发现了我的代码的问题。我们无法使用“in”运算符过滤具有索引值的数组。
【解决方案4】:

您可以利用String.protoype.splitArray.prototype.reduce 来解决这个问题。详情查看代码中的cmets:

const charCount = s => {
  //Create an array of characters found in the string (filtering out spaces)
  const chars = s.split('').filter(char => char.trim());

  //Use reduce to create an occurrence map - increment by 1 each time a character is encountered
  return chars.reduce((accum, char) => {
    accum[char] = accum[char] ? accum[char] + 1 : 1;
    return accum;
  }, {});
};

console.log(charCount("my name is Khan23"))

【讨论】:

    【解决方案5】:

    感谢大家的有用建议。我终于弄清楚我的代码出了什么问题。

    我的缺陷代码的输入和输出如下:

    输入:charCout("我叫 Khan23")

    预期输出:{2:1,3:1,a:2,e:1,h:1,i:1,k:1,m:2,n:2,s:1,y:1 }

    我得到了什么:{2:NaN,3:NaN,a:1,e:1,h:1,i:1,k:1,m:1,n:1,s:1,y: 1};

    我使用“in”运算符来确定字符串的特定值是否存在于 Object.keys(f) 数组中。这正是我出错的地方。

    在参考https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in 之后,我知道“in”不能用于使用索引值过滤数组。

    【讨论】:

      【解决方案6】:

      您可以使用str.split("") 获取字符列表,然后执行类似的操作

      const splitted = str.split("");
      const result = {};
      splitted.map(letter => result[letter] ? result[letter]++ : result[letter] = 1)
      

      这只是一个想法

      【讨论】:

        猜你喜欢
        • 2022-11-15
        • 2020-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        相关资源
        最近更新 更多