【问题标题】:Finding the nth occurrence of a character in a string in javascript在javascript中查找字符串中第n次出现的字符
【发布时间】:2012-10-05 11:10:37
【问题描述】:

我正在编写一个 javascript 代码来查找字符串中第 n 次出现的字符。使用 indexOf() 函数,我们可以得到字符的第一次出现。现在的挑战是让角色第 n 次出现。我能够使用下面给出的代码获得第二次第三次出现,依此类推:

function myFunction() {
  var str = "abcdefabcddesadfasddsfsd.";

  var n = str.indexOf("d");
  document.write("First occurence " +n );

  var n1 = str.indexOf("d",parseInt(n+1));
  document.write("Second occurence " +n1 );

  var n2 = str.indexOf("d",parseInt(n1+1));
  document.write("Third occurence " +n2 );

  var n3 = str.indexOf("d",parseInt(n2+1));
  document.write("Fourth occurence " +n3);

  // and so on ...
}

结果如下

First occurence 3 
Second occurence 9 
Third occurence 10 
Fourth occurence 14 
Fifth occurence 18 
Sixth occurence 19

我想概括脚本,以便我能够找到第 n 次出现的字符,因为上面的代码需要我们重复脚本 n 次。让我知道是否有更好的方法或替代方法来做同样的事情。如果我们只给出事件(在运行时)来获取该字符的索引,那就太好了。

以下是我的一些问题:

  • 我们如何在 JavaScript 中做到这一点?
  • 是否有任何框架提供任何功能以更简单的方式执行相同的实现,或者在其他框架/语言中实现相同的替代方法是什么?

【问题讨论】:

  • 只需将代码转换为循环。

标签: javascript


【解决方案1】:
function nth_occurrence (string, char, nth) {
    var first_index = string.indexOf(char);
    var length_up_to_first_index = first_index + 1;

    if (nth == 1) {
        return first_index;
    } else {
        var string_after_first_occurrence = string.slice(length_up_to_first_index);
        var next_occurrence = nth_occurrence(string_after_first_occurrence, char, nth - 1);

        if (next_occurrence === -1) {
            return -1;
        } else {
            return length_up_to_first_index + next_occurrence;  
        }
    }
}

// Returns 16. The index of the third 'c' character.
nth_occurrence('aaaaacabkhjecdddchjke', 'c', 3);
// Returns -1. There is no third 'c' character.
nth_occurrence('aaaaacabkhjecdddhjke', 'c', 3);

【讨论】:

  • 当我使用上面的代码通过警报显示事件时,我得到的输出是未定义的(对于第一次出现以外的任何值)。
  • 我修好了。问题是允许javascript解释器插入“;”他们认为适合的地方。所以他们在 return 之后放了一个,因为返回值在下一行,因此无法识别。
  • 返回字符串不在一行中,所以它显示未定义的输出。是我的错误。谢谢。
  • @CQQL 在第 n 次出现不存在的情况下失败 - 我希望它在这种情况下返回 -1 但它返回 [length up to previous index] -1 - 将编辑您的答案以修复
【解决方案2】:

您可以通过使用charAt() 实现一个函数来轻松做到这一点,如下所示:

function nth_ocurrence(str, needle, nth) {
  for (i=0;i<str.length;i++) {
    if (str.charAt(i) == needle) {
        if (!--nth) {
           return i;    
        }
    }
  }
  return false;
}

alert( nth_ocurrence('aaaaacabkhjecdddchjke', 'c', 3)  );//alerts 16

感谢 CQQL 让我知道 OP 真正想要什么。我更新了一些我原来的函数来实现新的行为。

【讨论】:

  • str.charAt(i)str[i] 相同 - 但您的代码计算出现次数,但找不到第 n 次出现。
  • 是的,名称“nth_ocurrence”与函数的作用不准确,但这是 OP 在描述他想要的东西时使用的名称,我认为这是我的函数所做的,所以我保留了该名称与 OP 的命名一致。
  • 所以让我们总结一下:您创建了一个具有 OP 引入的名称的函数,但没有达到预期的效果,也没有解决 OP 的问题。不错。
  • @CQQL 感谢您向我阐明 OP 真正想要什么,我只是修改了一些函数以实现预期的行为。您可能想检查一下,因为它使用的方法比您的更简单。
  • @myfashionhub 这是if (nth - 1 == 0) 的快捷方式,您也可以在这里了解前自增和后自增运算符stackoverflow.com/a/4706225/352672
【解决方案3】:

indexOf 接受第二个参数,即开始搜索的字符串中的字符索引。

function nthChar(string, character, n){
    var count= 0, i=0;
    while(count<n && (i=string.indexOf(character,i)+1)){
        count++;
    }
    if(count== n) return i-1;
    return NaN;
}

var s= 'abcbbasdbgasdnnaabaasdert';

nthChar(s,'a',7);

【讨论】:

    【解决方案4】:

    所以一个很好的方法是像这样扩展字符串类:

    (function() {
      String.prototype.nthOccurrenceIndex = function(charToMatch, occurrenceIndex) {
        var char, index, matches, _i, _len;
        matches = 0;
        index = 0;
        for (_i = 0, _len = this.length; _i < _len; _i++) {
          char = this[_i];
          if (char === charToMatch) {
            matches += 1;
            if (matches === occurrenceIndex) {
              return index;
            }
          }
          index += 1;
        }
        return -1;
      };
    
    }).call(this);
    

    更简洁的 CoffeeScript 版本:

    String.prototype.nthOccurrenceIndex = (charToMatch, occurrenceIndex)->
      matches = 0
      index = 0
    
      for char in @
        if char is charToMatch
          matches += 1
    
          return index if matches is occurrenceIndex
    
        index += 1
    
      -1
    

    所以现在您可以执行以下操作:

    "abcabc".nthOccurrenceIndex('a', 1)
    # -> 0

    "abcabc".nthOccurrenceIndex('a', 2)
    # -> 3

    "abcabc".nthOccurrenceIndex('a', 3)
    # -> -1

    【讨论】:

      【解决方案5】:

      一个可能更清晰的功能。 indexOf的递归复制机制:

      • 如果第 n 个数字(即 不正确,不会导致错误。它将返回-1,就像您可以将负数(或大于字符串的长度)作为fromIndex 提供给indexOf
      • 可以采用fromIndex 参数(与indexOf 相同:表示开始搜索的索引的整数;默认值为0。

      function indexOfNth (string, char, nth, fromIndex=0) {
        let indexChar = string.indexOf(char, fromIndex);
        if (indexChar === -1){
          return -1;
        } else if (nth === 1) {
          return indexChar;
        } else {
          return indexOfNth(string, char, nth-1, indexChar+1);
        }
      }
      
      
      let test = 'string for research purpose';
      console.log('first s:', indexOfNth(test, 's', 1));
      console.log('second s:', indexOfNth(test, 's', 2));
      console.log('15th s:', indexOfNth(test, 's', 15));
      console.log('first z:', indexOfNth(test, 'z', 1));
      console.log('-1th s:', indexOfNth(test, 's', -1));
      console.log('first s starting from index=1:', indexOfNth(test, 's', 1, 1));

      【讨论】:

        【解决方案6】:
        function nthIndexOf(search, n) {
            var myArray = []; 
            for(var i = 0; i < myStr.length; i++) {
                if(myStr.slice(i, i + search.length) === search) {
                    myArray.push(i);            
                }
            }   
            return myArray[n - 1];
        }
        

        【讨论】:

          猜你喜欢
          • 2011-02-04
          • 2010-12-25
          • 2016-11-21
          • 1970-01-01
          • 2013-09-26
          • 2018-08-24
          • 2018-03-22
          • 1970-01-01
          相关资源
          最近更新 更多