如何在C#中获取列表的前N个元素?
我想在我的项目中使用Linq查询公交车时刻表,这样我就可以随时得到接下来的5辆公交车的到达时间。如何将查询限制为前5个结果 更一般地说,如何在C#中获取列表的一部分?(在Python中,我将使用如何在C#中获取列表的前N个元素?,c#,C#,我想在我的项目中使用Linq查询公交车时刻表,这样我就可以随时得到接下来的5辆公交车的到达时间。如何将查询限制为前5个结果 更一般地说,如何在C#中获取列表的一部分?(在Python中,我将使用mylist[:5]获取前5个元素。) 或切片: var secondFiveItems = myList.Skip(5).Take(5); 当然,通常根据某种顺序获得前五项是很方便的: var firstFiveArrivals = myList.OrderBy(i => i.ArrivalTi
mylist[:5]
获取前5个元素。)
或切片:
var secondFiveItems = myList.Skip(5).Take(5);
当然,通常根据某种顺序获得前五项是很方便的:
var firstFiveArrivals = myList.OrderBy(i => i.ArrivalTime).Take(5);
如果有人感兴趣(即使问题没有要求这个版本),在C#2中应该是:(我已经编辑了答案,下面是一些建议)
myList.Sort(类\u用于\u比较器);
List fiveElements=myList.GetRange(0,5);
要获取前5个元素,最好使用如下表达式:
var firstFiveArrivals=myList.Where([EXPRESSION]).Take(5)代码>
或
var firstFiveArrivals=myList.Where([EXPRESSION]).Take(5).OrderBy([ORDER EXPR])代码>
它将比orderBy variant更快,因为LINQ引擎不会因为执行延迟而扫描所有列表,也不会对所有数组进行排序
class MyList : IEnumerable<int>
{
int maxCount = 0;
public int RequestCount
{
get;
private set;
}
public MyList(int maxCount)
{
this.maxCount = maxCount;
}
public void Reset()
{
RequestCount = 0;
}
#region IEnumerable<int> Members
public IEnumerator<int> GetEnumerator()
{
int i = 0;
while (i < maxCount)
{
RequestCount++;
yield return i++;
}
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
class Program
{
static void Main(string[] args)
{
var list = new MyList(15);
list.Take(5).ToArray();
Console.WriteLine(list.RequestCount); // 5;
list.Reset();
list.OrderBy(q => q).Take(5).ToArray();
Console.WriteLine(list.RequestCount); // 15;
list.Reset();
list.Where(q => (q & 1) == 0).Take(5).ToArray();
Console.WriteLine(list.RequestCount); // 9; (first 5 odd)
list.Reset();
list.Where(q => (q & 1) == 0).Take(5).OrderBy(q => q).ToArray();
Console.WriteLine(list.RequestCount); // 9; (first 5 odd)
}
}
类MyList:IEnumerable
{
int maxCount=0;
公共整数请求计数
{
得到;
私人设置;
}
公共MyList(整数最大计数)
{
this.maxCount=maxCount;
}
公共无效重置()
{
RequestCount=0;
}
#区域可数成员
公共IEnumerator GetEnumerator()
{
int i=0;
而(iq).Take(5.ToArray();
Console.WriteLine(list.RequestCount);//15;
list.Reset();
list.Where(q=>(q&1)==0.Take(5.ToArray();
Console.WriteLine(list.RequestCount);//9;(前5个奇数)
list.Reset();
list.Where(q=>(q&1)==0).Take(5).OrderBy(q=>q.ToArray();
Console.WriteLine(list.RequestCount);//9;(前5个奇数)
}
}
类似于分页
您可以使用以下公式获取列表或元素的片段
:
var slice = myList.Skip((pageNumber - 1) * pageSize)
.Take(pageSize);
例1:前五项
var pageNumber = 1;
var pageSize = 5;
var pageNumber = 2;
var pageSize = 5;
var pageNumber = 3;
var pageSize = 5;
例2:第二个五项
var pageNumber = 1;
var pageSize = 5;
var pageNumber = 2;
var pageSize = 5;
var pageNumber = 3;
var pageSize = 5;
例3:第三个五项
var pageNumber = 1;
var pageSize = 5;
var pageNumber = 2;
var pageSize = 5;
var pageNumber = 3;
var pageSize = 5;
如果对公式参数pageSize=5
和pageNumber
的注意正在更改,如果要更改切片中的项目数,请更改pageSize
也可以添加匿名谓词?List.Sort返回void;您需要进行排序,然后单独使用GetRange。您还可以使用比较匿名方法来消除对类“for”COMPARER的需要。@AlexeyMK-您是指比较,而不是谓词(谓词)-谓词用于过滤数据我相信这个答案即使在现在、10年后以及许多C版本之后仍然有用。对于有列表的特定情况。特别是如果你跳过了很多项目。例如,你有一张100万个项目的清单,你想要从清单中的5个项目中分一部分。GetRange确切地知道去哪里抓到它们。我不知道Skip
+Take
是否同样聪明,或者它是否会枚举跳过的项目。我不需要知道——我只使用GetRange(当给出一个列表时)。只需确保您意识到第二个参数是count(而不是最后一个索引)。.Take(n)
的好处在于,您不必担心它工作的序列中的元素是否少于n
。List.GetRange(0,count)
的问题在于您必须担心。。。。如果没有count
项目,您将得到一个ArgumentException
。除了您现在只在选择前5个元素后进行排序。它可能更快,但也有不同的语义,这不太可能是人们真正想要实现的。如果列表中只有,例如,3个项目,它会抛出异常吗?或者最多需要5个?它不会抛出异常。如果没有足够的元素,它只返回它所拥有的。确切地说,没有抛出异常Skip and Take combined解决了我的问题,因为我希望每个批处理任何通用集合和进程x项。应该注意,。Take(n)
返回Take迭代器;它不会返回包含n
元素的列表(假设有很多元素可用)。使用.ToArray()
或.ToList()
对Take
的结果进行排序,以获得具体的数组或列表。此外,看起来您实际上需要始终使用OrderBy。这是EntityFramework在异常消息中告诉我的,没有它:方法“Skip”仅支持LINQ to Entities中的排序输入。方法“OrderBy”必须在方法“Skip”之前调用。
我假设“Take”也一样,但我可能错了。您好,Mouad,谢谢您的回答。虽然您的代码可能会解决张贴的问题中的问题,但好的答案可以解释为什么您的解决方案有效。请考虑更新你的问题。