有没有一种很好的方法来枚举C#中只有一个Collection的子集?也就是说,我有一个大量对象的集合(比如1000),但是我想仅枚举元素250-340。有没有一个很好的方法来获取集合的子集的枚举器,没有使用另一个Collection?
编辑:应该提到这是使用.NET Framework 2.0。
答案 0 :(得分:36)
尝试以下
var col = GetTheCollection();
var subset = col.Skip(250).Take(90);
或者更一般地说
public static IEnumerable<T> GetRange(this IEnumerable<T> source, int start, int end) {
// Error checking removed
return source.Skip(start).Take(end - start);
}
编辑 2.0解决方案
public static IEnumerable<T> GetRange<T>(IEnumerable<T> source, int start, int end ) {
using ( var e = source.GetEnumerator() ){
var i = 0;
while ( i < start && e.MoveNext() ) { i++; }
while ( i < end && e.MoveNext() ) {
yield return e.Current;
i++;
}
}
}
IEnumerable<Foo> col = GetTheCollection();
IEnumerable<Foo> range = GetRange(col, 250, 340);
答案 1 :(得分:3)
我喜欢保持简单(如果你不一定需要枚举器):
for (int i = 249; i < Math.Min(340, list.Count); i++)
{
// do something with list[i]
}
答案 2 :(得分:2)
调整Jared的.Net 2.0原始代码:
IEnumerable<T> GetRange(IEnumerable<T> source, int start, int end)
{
int i = 0;
foreach (T item in source)
{
i++;
if (i>end) yield break;
if (i>start) yield return item;
}
}
使用它:
foreach (T item in GetRange(MyCollection, 250, 340))
{
// do something
}
答案 3 :(得分:1)
再次调整Jarad的代码,这种扩展方法将为您提供由 item 定义的子集,而不是索引。
//! Get subset of collection between \a start and \a end, inclusive
//! Usage
//! \code
//! using ExtensionMethods;
//! ...
//! var subset = MyList.GetRange(firstItem, secondItem);
//! \endcode
class ExtensionMethods
{
public static IEnumerable<T> GetRange<T>(this IEnumerable<T> source, T start, T end)
{
#if DEBUG
if (source.ToList().IndexOf(start) > source.ToList().IndexOf(end))
throw new ArgumentException("Start must be earlier in the enumerable than end, or both must be the same");
#endif
yield return start;
if (start.Equals(end))
yield break; //start == end, so we are finished here
using (var e = source.GetEnumerator())
{
while (e.MoveNext() && !e.Current.Equals(start)); //skip until start
while (!e.Current.Equals(end) && e.MoveNext()) //return items between start and end
yield return e.Current;
}
}
}
答案 4 :(得分:0)
你可以用Linq做点什么。我这样做的方法是将对象放入一个数组,然后我可以根据数组id选择我想要处理的项目。
答案 5 :(得分:0)
如果您发现需要对列表和集合进行大量切片和切割,那么将学习曲线推进到the C5 Generic Collection Library可能是值得的。