如何计算字符串中特定字符出现的次数?

16
我正在尝试创建一个函数,查看数组中的任何字符是否在字符串中出现,如果出现,计算出现次数。
我尝试计算每个模式,但是数量太多了。我尝试使用Python中“in”运算符的替代方法,但效果不佳。
function calc_fit(element) {
  var fitness_let = ["e", "l", "m", "n", "t"]

  }
}

element是一个字符串,而fitness_let数组是我需要检查的东西的数组,如果它们在字符串中出现了,就需要统计它们出现的次数。


这个问题为什么不是重复的?这是一个非常简单的问题,在JavaScript标签中已经有超过180万个问题被问过了。 - Peter Mortensen
1
@PeterMortensen 嗯,如果你能找到一个重复的问题,就投票关闭它。 - Carl Witthoft
6个回答

11

你可以使用 mapfilter 计算数组中具有相同值的出现次数:

let str="I love JavaScript and Node.js ";
let arr=str.replace(/[^a-zA-Z]/g, '').split('');

const mapped = [...new Set(arr)].map(a => `${a} occurs ${arr.filter(a1 => a1 === a).length  } time(s)`);
console.log(mapped);


1
我喜欢使用扩展语法。通过放弃 return 并使用字符串插值,您可以缩短代码。 - mwilson
@mwilson:谢谢,伙计,确实不需要返回值,在这里,我不知道为什么当我使用反引号时,堆栈溢出片段会给我语法错误。 - sumit
我看过JSFiddle做同样的事情。 - mwilson
1
@mwilson:啊,它起作用了,是我笨拙的手指打错了: )。感谢您的建议。 - sumit
你可以删除一些空格。而且你没有提到字节数。哦,等等,我一度以为自己在 https://codegolf.stackexchange.com/ 上... ;-) - Marco13
这确实是一个不错的解决方案,但它的时间复杂度为O(n^2),并且没有考虑到搜索特定字母(而不是全部字母)的特殊性,正如OP在第一段中所解释的那样:我正在尝试创建一个函数,查看数组中的任何字符是否在字符串中,并确定有多少个。 - Shidersz

3

首先,为了概括这种方法,最好让 calc_fit() 也将字母数组作为参数。然后,您可以使用计数器从 0 开始创建数组的Map。最后,遍历字符串并在需要时增加每个字母的相应计数器。

function calc_fit(element, fitness_let)
{
    // Create a Map from the array of letters to search.
    let map = new Map(fitness_let.map(l => ([l, 0])));

    // Traverse the string and increment counter of letters.    
    for (const c of element)
    {
        if (map.has(c))
            map.set(c, map.get(c) + 1);
    }
    
    return map;
}

let res = calc_fit("This is a string with some letters", ["e","l","m","n","t"]);
res.forEach((counter, letter) => console.log(`${letter} => ${counter}`));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}


0
一种方法是迭代数组并对每个字母进行全局正则表达式删除。然后,比较替换后的字符串长度与原始输入长度以确定出现次数。

function calc_fit(element) {
var fitness_let = ["e", "l", "m", "n", "t"];

for (var i=0; i < fitness_let.length; i++) {
    var letter = fitness_let[i];
    var numtimes = element.length - element.replace(new RegExp(letter, 'g'), '').length;
    console.log(fitness_let[i] + " occurs: " + numtimes + " times.");
}

}

var input = "elements are elemental";
calc_fit(input);


0
如果您想获取每个字符出现的次数,可以使用 reduceMap

let getTotal = (element) => {
  let fitness = ["e", "l", "m", "n", "t"]
  let newMap = new Map(fitness.map(v=>[v,v]))
  return element.split('').reduce((op,inp)=>{
    if(newMap.has(inp)){
      op[inp] = op[inp] || 0
      op[inp]++
    }
    return op
  },{})
}

console.log(getTotal('element'))
console.log(getTotal('eleabc'))


你可以使用join函数来构建一个带有交替符号|和单词边界的正则表达式,以获取总数。

let getTotal = (element) =>{
  let fitness = ["e", "l", "m", "n", "t"]
  let reg = '\\b' + fitness.join('|') + '\\b'
  let pattern = new RegExp(reg,'gi')
  return (element.match(pattern) || []).length
}

console.log(getTotal('element'))
console.log(getTotal('eleabc'))


0
你可以创建一个哈希映射表,并利用reduce来计算所有找到的实例数。
示例:

const counts = {};
["e", "l", "m", "n", "t"].forEach( e => counts[e] = 0 );
const letters = "hey look! a string!".split("");
const results = letters.reduce( (acc, curr) => {
 if (acc.hasOwnProperty(curr)) { acc[curr] += 1; }
  return acc;
}, counts);


console.log(results);


0

这里是一种略微不同的方法,依赖于函数生成器。

使用此方法没有任何相关原因优于其他解决方案,但它允许对整个周期进行额外控制。

顺便提一下,字符串仅迭代一次,因此整个“迭代”周期应该非常快。

解释直接在下面的代码中。

输出是一个对象,其中每个键都是一个字符,并保存出现次数,包含所有搜索的针。

如果未传递要搜索的字符数组,则会在calc_fit函数内自动构建,这将分别返回大写和小写出现次数,包括标点符号和符号。不过这很容易定制。

// Iterates a string and yield the current looped char if it exists in the chars list.
function* matchChars(s, chars) {
  for (var char of s) {
    if (chars.indexOf(char) > -1) yield { char: char };
  }
}

// not sure why the function was named in this way in the original code, but hey, it's the OP's function name.
function calc_fit(element, chars) {
  chars = chars || [...new Set(element)];
  // builds an object from the above array, where the structure has the key which is the char, and the value which is initially 0.
  const matchList = chars.reduce((acc,next) => (acc[next] = 0, acc), {});
  // Iterates all the matches. For each match, it increments the amount of matches of matchList.
  for (var match of matchChars(element, chars)) matchList[match.char]++;
  // finally, returns matchList.
  return matchList;
}

// assertions: should match all the characters.
console.log(calc_fit('element', ["e", "l", "m", "n", "t"]));
// assertions: should return all zeros.
console.log(calc_fit('', ["e", "l", "m", "n", "t"]));
// assertions: should automatically detect chars, even upper case and lower case.
console.log(calc_fit('hello, world. ThIs is beatiful!'));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接