質問

これを行うより良い方法はありますか?

string[] s = {"zero", "one", "two", "three", "four", "five"};

var x = 
s
.Select((a,i) => new {Value = a, Index = i})
.Where(b => b.Value.StartsWith("t"))
.Select(c => c.Index);

i.e。基準に一致するアイテムの位置を取得する、より効率的またはよりエレガントな方法を探しています。

役に立ちましたか?

解決

独自の拡張メソッドを簡単に追加できます:

public static IEnumerable<int> IndexesWhere<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
    int index=0;
    foreach (T element in source)
    {
        if (predicate(element))
        {
            yield return index;
        }
        index++;
    }
}

次に以下で使用します:

string[] s = {"zero", "one", "two", "three", "four", "five"};
var x = s.IndexesWhere(t => t.StartsWith("t"));

他のヒント

LINQを学習する方法として例を使用している場合は、この投稿を無視してください。


LINQが実際にこれを行う最良の方法であるかどうかは明確ではありません。以下のコードは、新しい匿名型を作成する必要がないため、より効率的だと思われます。確かに、あなたの例は工夫され、テクニックは別のコンテキスト、たとえば値のインデックスを利用できるデータ構造などでより有用かもしれませんが、以下のコードは合理的で分かりやすく理解できます(考えられません)必須)であり、おそらくより効率的です。

string[] s = {"zero", "one", "two", "three", "four", "five"};
List<int> matchingIndices = new List<int>();

for (int i = 0; i < s.Length; ++i) 
{
   if (s[i].StartWith("t"))
   {
      matchingIndices.Add(i);
   }
}

私にはいいようです。選択を次のように変更することで、数文字を保存できます。

.Select((Value, Index) => new {Value, Index})

コレクションリストには、コレクションからインデックスを返すことができるdeleteメソッドを作成するFindIndexメソッドもあります。 msdn http://msdn.microsoft.comの次のリンクを参照できます。 /en-us/library/x1xzf2ca.aspx

これはどうですか?元のポスターと似ていますが、最初にインデックスを選択してから、条件に一致するコレクションを作成します。

var x = s.Select((a, i) => i).Where(i => s[i].StartsWith("t"));

これは、リストが完全に2回繰り返されるため、他の回答のいくつかよりも効率が悪いです。

この興味深い問題を同僚と話し合って、最初はJonSkeetのソリューションは素晴らしいと思ったが、私の同僚は1つの問題を指摘した。つまり、関数がIEnumerable<T>の拡張である場合、実装します。

配列の場合、foreachで作成された順序は尊重されます(つまり、List.ToArrayは最初から最後まで繰り返されます)が、他のコレクション(リスト、辞書、など)、<=>は必然的に <!> quot;エントリの順序<!> quot;を反映しません。しかし、機能はそこにあり、誤解を招く可能性があります。

最終的に、私はtvanfossonの答えに似たものになりましたが、配列の拡張方法として:

public static int[] GetIndexes<T>(this T[]source, Func<T, bool> predicate)
{
    List<int> matchingIndexes = new List<int>();

    for (int i = 0; i < source.Length; ++i) 
    {
        if (predicate(source[i]))
        {
            matchingIndexes.Add(i);
        }
    }
    return matchingIndexes.ToArray();
}

ここでは、<=>が最後の操作の順序を尊重することを期待しています...

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