我有一个C#List<T>
个项目。我想从某个索引迭代到List<T>
项的末尾。我可以使用 foreach 语法执行此操作吗?
List<T> list = ...
foreach (var item in ???)
{
...
}
或任何其他方法?
e.g。从List.Count - 50
到结尾(我只想要最后 50
项目)
答案 0 :(得分:7)
由于Skip
实际枚举项目,因此List<T>
的效率不高:
public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count) {
if (source == null) throw Error.ArgumentNull("source");
return SkipIterator<TSource>(source, count);
}
...
static IEnumerable<TSource> SkipIterator<TSource>(IEnumerable<TSource> source, int count) {
using (IEnumerator<TSource> e = source.GetEnumerator()) {
while (count > 0 && e.MoveNext()) count--;
if (count <= 0) {
while (e.MoveNext()) yield return e.Current;
}
}
}
参见参考来源http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,90ccdbd47b57182e 详情;如果初始列表很长,我建议使用 for loop 并模拟 foreach 一个:
// the simplest in case list.Count >= 50
// foreach (var item in ...) {...} emulation
for (int i = list.Count - 50; i < list.Count; ++i) {
var item = list[i];
...
}
对于任意大小的列表(可以有更少的tan 50
项目)
for (int i = Math.Max(list.Count - 50, 0); i < list.Count; ++i) {
var item = list[i];
...
}
答案 1 :(得分:6)
尝试:
foreach (var item in list.Skip(Math.Max(0, list.Count - 50)))
如果您知道列表长度至少为50,则可以避免范围检查:
foreach (var item in list.Skip(list.Count-50))
虽然我确实只是写了for循环并避免任何花哨的东西:
for (int i = Math.Max(0, list.Count - 50); i < list.Count; ++i)
{
// Do something with list[i]
}
非范围检查版本:
for (int i = list.Count-50; i < list.Count; ++i)
{
// Do something with list[i]
}
答案 2 :(得分:4)
尝试使用以下内容:
newList = Enumerable.Reverse(list).Take(50).Reverse().ToList();
答案 3 :(得分:2)
鉴于您有一个IList<T>
(假设来自您的散文),那么您可以使用for
循环轻松抓取最后一个n
。这仍然会像LINQ -
public static IEnumerable<T> LastN<T>(this IList<T> list, int n)
{
if (list == null)
{
throw new ArgumentNullException("list");
}
if (list.Count - n < 0)
{
n = list.Count;
}
for (var i = list.Count - n; i < list.Count; i++)
{
yield return list[i];
}
}
// use
var tail50 = myList.LastN(50);
这也非常适合ICollection<T>
。
有一些实现ICollection<T>
的集合类型,例如LinkedList<T>
,如果你知道它们的具体类型,可能会有更有效的方法来完成你需要的东西。 (在这种情况下,对于LinkedList<T>
,上面的代码通常效率低下。
使用集合时要记住的一件事是IEnumerable<T>
以及它是无限序列的可能性。在这些情况下,除非你知道IEnumerable<T>
的具体类型或通过其他方式知道它是有限的,否则最好重新考虑获得&#34;最后n项&#34;,因为它甚至可能不可能。
答案 4 :(得分:1)
myList.Reverse(); // Reverse the list
lastFive = myList.Take(5); // Take the first 5 elements from the list.
myList.Reverse(); // Restore the list to its original order.