代码之家  ›  专栏  ›  技术社区  ›  Johann Gerell

使用LINQ,如何在特定索引中选择项?

  •  4
  • Johann Gerell  · 技术社区  · 14 年前

    如果我有 IEnumerable<Foo> allFoos 和一个 IEnumerable<Int32> bestFooIndexes ,我怎样才能换一个新的呢? IEnumerable<Foo> bestFoos 包含 Foo 条目来自 allFoos 在指定的索引处 bestFooIndexes ?

    6 回复  |  直到 14 年前
        1
  •  11
  •   Jon Skeet    14 年前

    以利沙的回答当然有效,但 可以 效率很低…这取决于什么 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
  •  12
  •   Elisha    14 年前
    var bestFoos = bestFooIndexes.Select(index => allFoos.ElementAt(index));
    

    如果您担心性能和收藏品数量大,请注意:

    List<Foo> allFoosList = allFoos.ToList();
    var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);
    
        3
  •  2
  •   PostMan    14 年前

    您可以创建这样的扩展方法:

    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);
    
        4
  •  1
  •   Adrian Zanescu    14 年前

    基于Join的另一个解决方案:

    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
  •  1
  •   Ani    14 年前

    乔恩·斯基特/伊莉莎的回答是前进的道路。

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

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

    包含的重复项 bestFooIndexes 不会在结果中产生重复项。此外,结果中的元素将按其枚举顺序排序 allFoos 而不是按照它们出现的顺序 最佳匹配项 .

        6
  •  0
  •   Kinjal    14 年前

    var bestfoosfromallfoos=allfoos.where((s)=>bestfoos.contains(s));