質問

私は Python のリスト内包表記が大好きです。リストの内包表記はリストの変換を簡潔に表すからです。

ただし、他の言語では、次のようなことを書いていることがよくあります。

foreach (int x in intArray)
  if (x > 3) //generic condition on x
    x++ 
    //do other processing

この例は C# で書かれています。LINQ がこれに役立つと思いますが、このややエレガントとは言えないソリューションを置き換えることができる一般的なプログラミング構造はあるのでしょうか?おそらく私が考慮していないデータ構造でしょうか?

役に立ちましたか?

解決

オリジナルの増分 foreach ループは配列の内容に影響を与えません。これを行う唯一の方法は依然として for ループ:

for(int i = 0; i < intArray.Length; ++i)
{
    if(intArray[i] > 3) ++intArray[i];
}

Linq は、既存のコレクションやシーケンスを変更することを目的としたものではありません。既存のシーケンスに基づいて新しいシーケンスを作成します。Linq を使用して上記のコードを実現することは可能ですが、目的とは少し異なります。

var newArray1 = from i in intArray select ((i > 3) ? (i + 1) : (i));
var newArray2 = intArray.Select(i => (i > 3) ? (i + 1) : (i));

使用する where (または同等の) は、他の回答の一部に示されているように、結果のシーケンスから 3 以下の値を除外します。

var intArray = new int[] { 10, 1, 20, 2 };
var newArray = from i in intArray where i > 3 select i + 1;
// newArray == { 11, 21 }

があります ForEach 配列のメソッドを使用すると、ラムダ関数の代わりにラムダ関数を使用できるようになります。 foreach ブロックしますが、メソッド呼び出し以外の場合はブロックします。 foreach.

intArray.ForEach(i => DoSomething(i));

他のヒント

C# では、次のように IEnumerable 内にあるものすべてに選択的な処理を適用できます。

intArray.Where(i => i > 3).ConvertAll();
DoStuff(intArray.Where(i => i 3));

等..

Python では、次のようになります。 フィルターとマップ, 、これであなたが望むことができます:

map(lambda x: foo(x + 1) filter(lambda x: x > 3, intArray))

それもあります リスト内包表記 これは 1 つの簡単なステートメントで両方を実行できます。

[f(x + 1) for x in intArray if x > 3]

Rubyでは:

intArray.select { |x| x > 3 }.each do |x|
  # do other processing
end

または、「その他の処理」が短いワンライナーの場合:

intArray.select { |x| x > 3 }.each { |x| something_that_uses x }

最後に、3 より大きい要素の処理結果を含​​む新しい配列を返したい場合は、次のようにします。

intArray.select { |x| x > 3 }.map { |x| do_something_to x }
map(lambda x: test(x + 1) filter(lambda x: x > 3, arr))

言語と何をする必要があるかによって異なりますが、多くの言語で「マップ」と呼ばれるものが探しているものになる可能性があります。C#は分かりませんが、によると これ ページでは、.NET 2.0 はマップを「ConvertAll」と呼びます。

「マップ」の意味は非常に単純です。リストを取得し、その各要素に関数を適用して、新しいリストを返します。また、別のリストの述語を満たす項目のリストを提供する「フィルター」を探している場合もあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top