たとえば、次の文字列があるとします。
var testString = "こんにちは、世界";
そして、次のメソッドを呼び出したい:
var newString = testString.Replace("こんにちは", "").Replace("世界", "");
これを簡素化するコード構造があり、Replace メソッドを 1 回指定するだけで、一連のパラメーターを指定して一度に渡すことができますか?
たとえば、次の文字列があるとします。
var testString = "こんにちは、世界";
そして、次のメソッドを呼び出したい:
var newString = testString.Replace("こんにちは", "").Replace("世界", "");
これを簡素化するコード構造があり、Replace メソッドを 1 回指定するだけで、一連のパラメーターを指定して一度に渡すことができますか?
これを読みやすくする別のオプションは、新しい行と適切なインデントを追加することです (これは私にとってより良いオプションです):
var newString = testString.Replace("Hello", "")
.Replace("world", "")
.Replace("and", "")
.Replace("something", "")
.Replace("else","");
String
とを渡す関数を作成しますDictionary(String, String)
。Dictionary と の各項目を反復処理しますInputString.Replace(DictionaryEntry.Key, DictionaryEntry.Value)
。値を置き換えた文字列を返します。
でも.Replace.Replace
2回だけならいいけど…
一部の言語 (Python など) には、reduce または fold 関数の概念があります。これは、リスト内のすべての要素に対するループを表す機能的な方法です。
reduce を使用すると、このようなものを書くことができます
return reduce(ラムダ a, x: a.Replace(x, ''), ['hello', 'world'], initial)
これはと同じです
a = イニシャル for x in ['hello', 'world']: a = a.Replace(x, '') 返す
Python では、これを次のように発音することもできます。
reduce(str.replace, ['hello', 'world'], initial)。
もちろん、これがより単純かどうかはまったく別の問題ですが、多くの人は確かにこのようなコードを書くことを楽しんでいます。
他の投稿で述べたように、多くの方法があります。
しかし、一般的には、甘い = 効率的 (= 保守可能) = シンプルです。質問のコンテキストを説明している以上の理由がない限り、試してみるのがおそらく最善です。
IEnumberable パラメーターを受け取る独自の Replace 拡張メソッドを作成できます。次に、反復子をループして、replace メソッドを使用します。
次に、次のように呼び出すことができます。Replace(new string[] {"Matt", "Joanne", "Robert"}, "")
これでやればいいと思う
public static string Replace(this string s, IEnumerable<string> strings, string replacementstring)
{
foreach (var s1 in strings)
{
s = s.Replace(s1, replacementstring);
}
return s;
}
次のような正規表現でそれを行うことができます。
var newString = Regex.Replace(testString, "Hello|world", "");
シーケンスからプログラムで正規表現を構築したい場合は、次のようになります。
var stringsToReplace = new[] { "Hello", "world" };
var regexParts = stringsToReplace.Select(Regex.Escape);
var regexText = string.Join("|", regexParts.ToArray());
あなたが思いついた構成は、おそらく元の投稿よりも複雑になるでしょう。渡すパラメータが非常に多い場合は、それらの引数のベクトルを構築し、呼び出しを実行することを繰り返すことができます。しかし、繰り返しになりますが、現在の例では、変更されたバージョンは長くなり、書くのがより複雑になります。2回は繰り返し率が小さすぎます。
これが甘いかどうかはわかりませんが、次のことができます。
string inputString = "Hello, world";
string newString = new[] { "Hello", "world" }.Aggregate(inputString, (result, replace) => result.Replace(replace, ""));
これは入力文字列をシードとして開始し、各置換文字列で関数を実行します。
Aggregate 関数を理解するためのより良い例は、おそらく次のようになります。
List<Payment> payments = ...;
double newDebt = payments.Aggregate(oldDebt, (debt, payment) => debt - payment.Amount);
多くの人が IEnumerable と List と Arrays などを使用する必要があると言っています。ただし、このようなものを実装する場合は、二重の Replace メソッド呼び出しのような簡単なことはしたくないでしょう...
私が見ているこれらのパターンにはいくつかの落とし穴があります。まず第一に、特に入力文字列が大きい場合は、replace を数回呼び出すか、ループ内で文字列が不変になると、問題が発生する可能性があります。replace の呼び出しに熱中している場合は、少なくとも StringBuilder クラスの Replace メソッドを使用してください。