3

我有一个清单CustomClassItem。我有几个整数,它们是我要检索的项目的索引。

获得它们的最快/最有效的方法是什么?具有多个索引的索引运算符的精神还是可能myList.GetWhereIndexIs(myIntsList)

4

4 回答 4

7

您可以使用 Linq:

List<CustomClassItem> items = myIntsList.Select(i => myList[i]).ToList();

确保myIntsList.All(i => i >= 0 && i < myList.Count);

编辑:

如果列表中不存在索引,请忽略此索引:

List<CustomClassItem> items = myIntsList.Where(i => i >= 0 && i < myList.Count)
                                        .Select(i => myList[i]).ToList();
于 2013-06-19T12:16:58.803 回答
5

我认为一个不错且有效的解决方案是yield与扩展方法结合使用:

public static IList<T> SelectByIndex<T>(this IList<T> src, IEnumerable<int> indices)
{
    foreach (var index in indices) {
        yield return src[index];
    }
}

现在你可以这样做:myList.SelectByIndex(new [] { 0, 1, 4 });

您还可以使用 params 对象:

public static IList<T> SelectByIndexParams<T>(this IList<T> src, params int[] indices)
{
    foreach (var index in indices) {
        yield return src[index];
    }
}

现在你可以这样做:myList.SelectByIndexParams(0, 1, 4);

于 2013-06-19T12:18:42.740 回答
2

你想要的(如果我没看错的话)如下:

var indices = [ 1, 5, 7, 9 ];
list.Where((obj, ind) => indices.Contains(ind)).ToList();

这将为您提供List<CustomClassItem>包含索引在列表中的所有项目。

几乎所有的 LINQ 扩展方法都接受一个带有 T一个 int 的函数,即 Enumerable 中 T 的索引。它真的很方便。

于 2013-06-19T12:25:04.533 回答
2

另一种方法使用Enumerable.Join

var result = myList.Select((Item, Index) => new { Item, Index })
    .Join(indices, x => x.Index, index => index, (x, index) => x.Item);

更高效、更安全(确保索引存在)但比其他方法可读性差。

演示

也许您想创建一个扩展来增加可读性和可重用性:

public static IEnumerable<T> GetIndices<T>(this IEnumerable<T> inputSequence, IEnumerable<int> indices)
{
    var items = inputSequence.Select((Item, Index) => new { Item, Index })
       .Join(indices, x => x.Index, index => index, (x, index) => x.Item);
    foreach (T item in items)
        yield return item;
}

然后你可以这样使用它:

var indices = new[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var first5 = myList.GetIndices(indices).Take(5);

用于Take证明 linq 的延迟执行在这里仍然有效。

于 2013-06-19T12:25:05.180 回答