如果我有IEnumerable<Foo> allFoos
和IEnumerable<Int32> bestFooIndexes
,如何在指定的索引处获取包含IEnumerable<Foo> bestFoos
Foo
条目的新allFoos
bestFooIndexes
?
答案 0 :(得分:12)
var bestFoos = bestFooIndexes.Select(index => allFoos.ElementAt(index));
如果你担心表演并且收藏很大,那么:
List<Foo> allFoosList = allFoos.ToList();
var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);
答案 1 :(得分:11)
Elisha的答案肯定会有效,但可能效率非常低......这取决于allFoos
的实施情况。如果它是IList<T>
的实现,ElementAt
将是有效的 - 但如果它实际上是(例如)LINQ to Objects查询的结果,那么将为每个索引重新运行查询。所以可能更有效率地写作:
var allFoosList = allFoos.ToList();
// Given that we *know* allFoosList is a list, we can just use the indexer
// rather than getting ElementAt to perform the optimization on each iteration
var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);
当你需要的时候,你可以这样做:
IList<Foo> allFoosList = allFoos as IList<Foo> ?? allFoos.ToList();
var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);
答案 2 :(得分:2)
你可以像这样制作一个扩展方法:
public IEnumerable<T> ElementsAt(this IEnumerable<T> list, IEnumerable<int> indexes)
{
foreach(var index in indexes)
{
yield return list.ElementAt(index);
}
}
然后你可以这样做
var bestFoos = allFoos.ElementsAt(bestFooIndexes);
答案 3 :(得分:1)
Jon Skeet / Elisha的答案是要走的路。
这是一个稍微不同的解决方案,很可能效率不高:
var bestFooIndices = new HashSet<int>(bestFooIndexes);
var bestFoos = allFoos.Where((foo, index) => bestFooIndices.Contains(index));
bestFooIndexes
中包含的重复不会在结果中产生重复。此外,结果中的元素将按其allFoos
中的枚举顺序排序,而不是按bestFooIndexes
中的顺序排序。
答案 4 :(得分:1)
另一种基于联接的解决方案:
var bestFoos = from entry in allFoos
.Select((a, i) = new {Index = i, Element = a})
join index in bestFooIndexed on entry.Index equals index
select entry.Element;
答案 5 :(得分:0)
var bestFoosFromAllFoos = allFoos.Where((s)=&gt; bestFoos.Contains(s));