参考
この記事は、以下の動画を参考にしています。詳しくは、動画をご覧ください。
また、リファレンスも参考にしてください。
SearchValue<T>
- コレクションを引数にして、インスタンスを生成する
- インスタンスに対して
Contains
メソッドを呼び、引数にした値が含まれているかどうかを戻す - .NET 8では、コレクションのデータ型は
char
またはbyte
のみ - .NET 9では、加えて
string
も可能 - どのように
string
を比較するかは、インスタンスを生成するときに、StringComparison
を渡して、あらかじめ決める。Contains
を呼ぶときにはStringComparison
を変更できない
訂正(追記)
参考にした動画に、訂正が入りました。
この記事も、訂正させていただきます。
Containsメソッドが本題ではない
SearchValues<T>.Contains
メソッドは、SearchValues<T>
を単にHashSet<T>
として使っているだけである。実際にパフォーマンスは同等である。
長大な文字列から部分文字列を探す
長いstring
に、特定の単語が含まれているかを調べたいとする。
string.Contains
メソッドを使うと、次のようになる。
string longText = new HttpClient()
.GetStringAsync("https://www.gutenberg.org/cache/epub/100/pg100.txt")
.GetAwaiter()
.GetResult();
var targetWords = ["target", "words"];
var found = targetWords.Any(x => longText.Contains(x, StringComparison.OrdinalIgnoreCase);
// foundがtrueなら、targetWordsのいずれかを見つけた
SearchValues<string>
を引数にするContainsAny
拡張メソッドを使うと、以下のように記述できる。
ReadOnlySpan<char> longText = new HttpClient()
.GetStringAsync("https://www.gutenberg.org/cache/epub/100/pg100.txt")
.GetAwaiter()
.GetResult();
var targetWords = SearchValues.Create(["target", "words"],
StringComparison.OrdinalIgnoreCase);
var found = longText.ContainsAny(targetWords);
// foundがtrueなら、targetWordsのいずれかを見つけた
手元の実行環境では、後者は前者に比べて約半分の実行時間になった。
文字列に対してSearchValues<string>を引数にして呼び出せる拡張メソッド
以下の拡張メソッドが、System.MemoryExtensions
クラスで定義されている。(.NET 9 Preview 2時点)
ContainsAny
IndexOfAny
いずれのメソッドも、第1引数はSpan<char>
またはReadOnlySpan<char>
、第2引数はSearchValue<string>
である。