IndexOf
、IndexOfAny
とLastIndexOf
、LastIndexOfAny
find_last_not_ofは、これらの操作を行うように見えるいけない(または多分彼らはありません)。私はstd :: stringのfind_first_not_of
とfind_last_not_of
の等価を探しています。私は拡張クラスを作成することを考えていますが、C#が既にこの機能を提供しているかどうかはわかりません。のC#C++のstd ::文字列find_first_not_ofの同等と
答えて
string source = "the quick brown fox jumps over the lazy dog";
string chars = "ogd hte";
int? firstNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
.Where(x => chars.IndexOf(x.Val) == -1)
.Select(x => x.Idx)
.FirstOrDefault();
int? lastNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
.Where(x => chars.IndexOf(x.Val) == -1)
.Select(x => x.Idx)
.LastOrDefault();
それとも、あなたはいくつかの非LINQの拡張メソッドを好む場合。これらは、特にFindLastNotOf
のために、わずかに良いパフォーマンスを持っている必要があります、あなたはHashSet<char>
にchars
を変換する場合 - - LINQと非LINQの両方のバージョンで
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;
}
を(それはあなたががより良いパフォーマンスを得るかもしれないということが可能ですまたはchar[]
配列であっても、ベンチマークを行う必要があります。chars
がかなり大きくならない限り、違いは無視しても問題ありません。)
LINQを使用できる場合は、First()とLast()メソッドを適切な述語で呼び出すことができます。例えば
、あなたが母音ではありません最初と最後の文字たい場合:
string vowels = "aeiouy";
char first = yourString.First(ch => vowels.IndexOf(ch) < 0);
char last = yourString.Last(ch => vowels.IndexOf(ch) < 0);
をEDIT:上記そのインデックス、文字はないが返されます。そのためには、あなたがSelect()メソッドを使用してインデックスを投影することができ、私たちは何の文字が一致しない場合-1
を返却する必要があるので、物事が毛深いなります。また
int firstIndex = (yourString.Select(
(ch, i) => new { Character = ch, Index = i }
).First(obj => vowels.IndexOf(obj.Character) < 0)
?? new { Character = '\0', Index = -1 }).Index;
int lastIndex = (yourString.Select(
(ch, i) => new { Character = ch, Index = i }
).Last(obj => vowels.IndexOf(obj.Character) < 0)
?? new { Character = '\0', Index = -1 }).Index;
、ここに@ abatishchevさんに基づくそれほど複雑ソリューションです答え:
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));
正確には 'find_first_not_of'は文字ではなく位置を返します。 – Vlad
@Vlad、あなたが正しいです、それに応じて更新答えます。ありがとう:) –
私はLINQは事をovercomplicatesだと思う。そして、このソリューションは非常に効果がありません。私たちはイテレータと一緒に匿名型の一時オブジェクトのロットを作成しています。ループのための単純な方法を書く方が良いでしょう。 –
ここには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;
いい仕事ですが、正しい考え方では、ライブラリやAPIルーチンで受け入れられるものはどれですか? MSが失敗したように見えます。 – GTAE86