[英]Getting a collection of index values using a LINQ query
有一個更好的方法嗎?
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);
即我正在尋找一種更有效或更優雅的方式來獲得符合標准的物品的位置。
您可以輕松添加自己的擴展方法:
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})
Collection List中還有FindIndex方法,您可以為其創建一個可以從集合中返回索引的delete方法。 您可以參考msdn http://msdn.microsoft.com/en-us/library/x1xzf2ca.aspx中的以下鏈接。
這個怎么樣? 它類似於原始海報,但我首先選擇索引,然后構建一個符合標准的集合。
var x = s.Select((a, i) => i).Where(i => s[i].StartsWith("t"));
這比其他一些答案效率低,因為列表完全迭代了兩次。
我和一位同事討論了這個有趣的問題,起初我認為JonSkeet的解決方案很棒,但是我的同事指出了一個問題,即如果函數是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
會尊重最后一次操作的順序......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.