17

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

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);

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

4

6 に答える 6

32

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

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"));
于 2008-10-26T07:15:57.077 に答える
6

この例を 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);
   }
}
于 2008-10-26T03:10:09.943 に答える
5

私には問題ないようです。選択を次のように変更することで、いくつかの文字を節約できます。

.Select((Value, Index) => new {Value, Index})
于 2008-10-26T02:03:08.080 に答える
2

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

于 2009-04-16T13:53:52.333 に答える
1

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

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

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

于 2009-06-24T03:12:28.130 に答える
0

私は同僚とこの興味深い問題について議論し、最初は JonSkeet の解決策が素晴らしいと思っていましたが、同僚は 1 つの問題を指摘しましIEnumerable<T>た。

foreach「_ foreach_ foreach_ _ _入場順」。それでも機能はありますが、誤解を招く可能性があります。

結局、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();
}

List.ToArray最後の操作の順序を尊重することを願っています...

于 2011-10-20T00:07:21.097 に答える