25

我正在编写一个 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 中做到这一点?
  • 是否有任何框架提供任何功能以更简单的方式执行相同的实现,或者在其他框架/语言中实现相同的替代方法是什么?
4

6 回答 6

24
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);
于 2012-10-05T11:22:05.440 回答
14

您可以通过使用 实现一个函数来轻松地做到这一点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 真正想要什么。我更新了一些我原来的功能来实现新的行为。

于 2012-10-05T11:15:30.280 回答
8

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);
于 2012-10-05T13:57:02.983 回答
2

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

(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

于 2014-09-15T09:02:30.633 回答
2

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

  • 如果 nth 的数字不正确(即 <= 0),不会导致错误。它将返回-1,就像您可以给出一个负数(或大于字符串的长度)fromIndex一样indexOf
  • 可以带fromIndex参数(与 for 相同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));

于 2019-08-01T06:26:36.007 回答
0
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];
}
于 2016-05-31T15:05:00.843 回答