C# 使用LINQ,如何选择特定索引处的项?

C# 使用LINQ,如何选择特定索引处的项?,c#,linq,ienumerable,C#,Linq,Ienumerable,如果我有一个IEnumerable-allFoos和一个IEnumerable-bestFooIndexes,我如何获得一个新的IEnumerable-bestFoos,其中包含allFoos中bestFooIndexes指定索引处的Foo条目 var bestFoos = bestFooIndexes.Select(index => allFoos.ElementAt(index)); 如果您担心性能,而且收藏量很大,请: List<Foo> allFoosList = a

如果我有一个
IEnumerable-allFoos
和一个
IEnumerable-bestFooIndexes
,我如何获得一个新的
IEnumerable-bestFoos
,其中包含
allFoos
bestFooIndexes
指定索引处的
Foo
条目

var bestFoos = bestFooIndexes.Select(index => allFoos.ElementAt(index));
如果您担心性能,而且收藏量很大,请:

List<Foo> allFoosList = allFoos.ToList();
var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);
List allFoosList=allFoos.ToList();
var bestFoos=bestfoodexes.Select(index=>allFoosList[index]);

以利沙的回答肯定会奏效,但可能效率很低。。。这取决于allFoos的实现方式。如果它是
IList
的一个实现,
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]);
IList allFoosList=allFoos作为IList??allFoos.ToList();
var bestFoos=bestfoodexes.Select(index=>allFoosList[index]);

您可以创建如下扩展方法:

public IEnumerable<T> ElementsAt(this IEnumerable<T> list, IEnumerable<int> indexes)
{
     foreach(var index in indexes)
     {
           yield return list.ElementAt(index);
     }

}

Jon Skeet/Elisha的答案是正确的

这里有一个稍有不同的解决方案,很可能效率较低:

var bestFooIndices = new HashSet<int>(bestFooIndexes);
var bestFoos = allFoos.Where((foo, index) => bestFooIndices.Contains(index));
var bestFooIndexes=新哈希集(bestFooIndexes);
var bestFoos=allFoos.Where((foo,index)=>bestfoodindexs.Contains(index));

bestFooIndexes
中包含的重复不会在结果中产生重复项。此外,结果中的元素将按照它们在
allFoos
中的枚举顺序排序,而不是按照它们在
bestfoodexites
中的出现顺序排序另一个基于联接的解决方案:

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;

var bestFoosFromAllFoos=allFoos.Where((s)=>bestFoos.Contains)列表。但如果我把问题缩小到这个事实上,下面的答案和讨论就不会那么有趣了@奥斯卡是的,我很抱歉,我错过了标签。不知道。我喜欢它-它与我已经用来挑选的东西押韵:
var bestFoo=allFoos.ElementAtOrDefault(bestfoodindex)
你可能是指
bestfoodexes.Select(index=>allFoosList[index]
@Henrik:我前几天才第一次用过它:)以利沙没有得到公认的答案似乎是不公平的,因为他第一个得到的答案是相同的。@Bear:以利沙的答案是好的,但乔恩的加糖使它变得更好。我没有明确地想到。。。如果它是IList的一个实现,ElementAt将是高效的。。。而且我也喜欢做IList??allFoos.ToList()@Johann好的,谢谢你的回答。只是为弱者而战;)是的,ICollection和IList的Linq优化总体上做得很好。我现在会停止用无聊的评论来污染你的帖子:)
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;