我有CustomClassItem
的列表。我有几个int是我想要检索的项目的索引。
获得它们的最快捷/最有效的方法是什么?索引运算符的精神中有多个索引或者myList.GetWhereIndexIs(myIntsList)
?
答案 0 :(得分: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();
答案 1 :(得分: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);
答案 2 :(得分:2)
你想要什么(如果我正确阅读)如下:
var indices = [ 1, 5, 7, 9 ];
list.Where((obj, ind) => indices.Contains(ind)).ToList();
这将为您提供List<CustomClassItem>
,其中包含其索引位于列表中的所有项目。
几乎所有的LINQ扩展方法都接受一个函数,它将T 和作为一个int,即Enumerable中的T的索引。这真的很方便。
答案 3 :(得分: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的延迟执行仍然适用于此。