C'est en gros ce que vous devez faire - ou du moins, c'est la solution la plus simple. Tout ce que vous "gaspilleriez", c'est le coût de n invocations de méthodes - vous ne vérifierez en fait pas deux fois chaque cas, si vous y réfléchissez bien. (IndexOf reviendra dès qu'il aura trouvé la correspondance, et vous continuerez là où il s'est arrêté).
Voici l'implémentation récursive (de ce qui précède) idée ) comme méthode d'extension, imitant le format de la ou des méthodes du cadre :
public static int IndexOfNth(this string input,
string value, int startIndex, int nth)
{
if (nth < 1)
throw new NotSupportedException("Param 'nth' must be greater than 0!");
if (nth == 1)
return input.IndexOf(value, startIndex);
var idx = input.IndexOf(value, startIndex);
if (idx == -1)
return -1;
return input.IndexOfNth(value, idx + 1, --nth);
}
Voici également quelques tests unitaires (MBUnit) qui pourraient vous aider (à prouver que c'est correct) :
using System;
using MbUnit.Framework;
namespace IndexOfNthTest
{
[TestFixture]
public class Tests
{
//has 4 instances of the
private const string Input = "TestTest";
private const string Token = "Test";
/* Test for 0th index */
[Test]
public void TestZero()
{
Assert.Throws<NotSupportedException>(
() => Input.IndexOfNth(Token, 0, 0));
}
/* Test the two standard cases (1st and 2nd) */
[Test]
public void TestFirst()
{
Assert.AreEqual(0, Input.IndexOfNth("Test", 0, 1));
}
[Test]
public void TestSecond()
{
Assert.AreEqual(4, Input.IndexOfNth("Test", 0, 2));
}
/* Test the 'out of bounds' case */
[Test]
public void TestThird()
{
Assert.AreEqual(-1, Input.IndexOfNth("Test", 0, 3));
}
/* Test the offset case (in and out of bounds) */
[Test]
public void TestFirstWithOneOffset()
{
Assert.AreEqual(4, Input.IndexOfNth("Test", 4, 1));
}
[Test]
public void TestFirstWithTwoOffsets()
{
Assert.AreEqual(-1, Input.IndexOfNth("Test", 8, 1));
}
}
}
0 votes
J'utiliserais une expression régulière pour cela, puis il faut trouver un moyen optimal de faire correspondre la chaîne dans la chaîne. C'est l'un des beaux DSL que nous devrions tous utiliser lorsque c'est possible. Un exemple en VB.net, le code est presque le même qu'en C#.
2 votes
Je parierais sur le fait que la version des expressions régulières est beaucoup plus difficile à mettre en place que "continuer à faire des boucles et à faire de simples String.IndexOf". Les expressions régulières ont leur place, mais ne devraient pas être utilisées lorsque des alternatives plus simples existent.
0 votes
Similaire : stackoverflow.com/a/9908392/1305911