9
votes

C # équivalent de c ++ std :: string wind_first_not_of and wind_last_not_of

indexof , indexofany et lastIndexof , lastIndexofany ne semble pas faire ces (ou peut-être qu'ils font). Je cherche l'équivalent de STD :: String's Find_First_Not_of et FIND_LAST_NOT_OF . Je pense à créer une classe d'extension mais je ne sais pas si c # fournit déjà cette fonctionnalité.


0 commentaires

3 Réponses :


4
votes

Si l'utilisation de LINQ est acceptable, vous pouvez appeler le premier () et Dernier () Méthodes avec le prédicat approprié.

Par exemple, si vous voulez que les premier et les derniers caractères ne soient pas voyelles: p> xxx pré>

edit: strong> Ce qui précède retournera les caractères, non leurs index. Pour ce faire, vous pouvez projeter les index à l'aide du Sélectionnez () A > Méthode, mais les choses vont devenir poilues car nous devons retourner -1 code> si aucun caractère correspond: p> xxx pré>

alternativement, voici une solution moins compliquée Réponse de @ Abatishchev: P>

string vowels = "aeiouy";
int firstIndex = yourString.IndexOf(yourString.First(
    ch => vowels.IndexOf(ch) < 0));
int lastIndex = yourString.LastIndexOf(yourString.Last(
    ch => vowels.IndexOf(ch) < 0));


4 commentaires

Pas exactement: wind_first_not_of renvoie la position, pas le personnage.


Je pense que Linq surcharge des choses. Et cette solution est très inefficace. Nous créons beaucoup d'objets temporaires de type anonyme et d'itérateurs. Méthode d'écriture qui fait simple pour la boucle sera meilleure.


Vous voulez probablement utiliser les méthodes d'extension de SleeTeDefault et de FirstOrdefault pour supprimer la lancée des exceptions. Ou il me manque quelque chose?


@DMitry, puisque j'utilise des types anonymes, ces méthodes de retourneraient null et l'accès ultérieur à l'index échoueraient. Puisque je voulais retourner -1 dans ce contexte, j'ai dû créer une instance explicite du type anonyme avec index défini sur -1 . Je suis d'accord que ça sort de la main, cependant :)



12
votes
int? firstNotOf = source.FindFirstNotOf(chars);
int? lastNotof = source.FindLastNotOf(chars);

// ...

public static int? FindFirstNotOf(this string source, string chars)
{
    if (source == null) throw new ArgumentNullException("source");
    if (chars == null) throw new ArgumentNullException("chars");
    if (source.Length == 0) return null;
    if (chars.Length == 0) return 0;

    for (int i = 0; i < source.Length; i++)
    {
        if (chars.IndexOf(source[i]) == -1) return i;
    }
    return null;
}

public static int? FindLastNotOf(this string source, string chars)
{
    if (source == null) throw new ArgumentNullException("source");
    if (chars == null) throw new ArgumentNullException("chars");
    if (source.Length == 0) return null;
    if (chars.Length == 0) return source.Length - 1;

    for (int i = source.Length - 1; i >= 0; i--)
    {
        if (chars.IndexOf(source[i]) == -1) return i;
    }
    return null;
}

1 commentaires

Beau travail, mais qui, dans leur bon esprit, trouve l'une de ces personnes acceptables sur une routine de bibliothèque ou d'API? On dirait qu'une MS échoue.



0
votes

Voici une solution de regex.

string testString = "oueytestie";
var matchFirstNotOf = Regex.Match(testString, @"[^aeiouy]");
int firstNotOf = matchFirstNotOf.Success ? matchFirstNotOf.Index : -1;
var matchLastNotOf = Regex.Match(testString, @"[^aeiouy]", RegexOptions.RightToLeft);
int lastNotOf = matchLastNotOf.Success ? matchLastNotOf.Index : -1;


0 commentaires