【发布时间】:2010-09-24 02:44:30
【问题描述】:
我想在我的项目中使用 Linq 查询公交时刻表,以便随时可以获取接下来的 5 趟公交车到达时间。如何将我的查询限制为前 5 个结果?
更一般地说,如何在 C# 中获取列表的一部分? (在 Python 中,我会使用 mylist[:5] 来获取前 5 个元素。)
【问题讨论】:
标签: c#
我想在我的项目中使用 Linq 查询公交时刻表,以便随时可以获取接下来的 5 趟公交车到达时间。如何将我的查询限制为前 5 个结果?
更一般地说,如何在 C# 中获取列表的一部分? (在 Python 中,我会使用 mylist[:5] 来获取前 5 个元素。)
【问题讨论】:
标签: c#
var firstFiveItems = myList.Take(5);
或者切片:
var secondFiveItems = myList.Skip(5).Take(5);
当然,根据某种顺序获取前五个项目通常很方便:
var firstFiveArrivals = myList.OrderBy(i => i.ArrivalTime).Take(5);
【讨论】:
.Take(n)返回的是TakeIterator;它不会返回包含 n 元素的列表(假设有很多可用)。在Take 的结果上使用.ToArray() 或.ToList() 以获取具体的数组或列表。
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'. 我假设“Take”是一样的,但我可能错了。
如果有人感兴趣(即使问题没有要求这个版本),在 C# 2 中将是:(我已经编辑了答案,遵循了一些建议)
myList.Sort(CLASS_FOR_COMPARER);
List<string> fiveElements = myList.GetRange(0, 5);
【讨论】:
Skip + Take 是否一样聪明,或者它是否枚举了跳过的项目。而且我不需要知道——我只使用 GetRange(当给定一个列表时)。只要确保你意识到第二个参数是 count(而不是 last index)。
.Take(n) 的好处在于,如果它处理的序列中的元素少于n,您不必担心。 List<T>.GetRange(0, count) 的问题是你必须担心....如果没有 count 项目,你会得到一个 ArgumentException。
像pagination一样,你可以使用下面的公式来获取slice of list or elements:
var slice = myList.Skip((pageNumber - 1) * pageSize)
.Take(pageSize);
示例 1:前五项
var pageNumber = 1;
var pageSize = 5;
示例 2:后五项
var pageNumber = 2;
var pageSize = 5;
示例3:第三五项
var pageNumber = 3;
var pageSize = 5;
如果注意公式参数
pageSize = 5和pageNumber发生变化,如果要更改切片中的项目数,请更改pageSize。
【讨论】:
要获取前 5 个元素,最好使用如下表达式:
var firstFiveArrivals = myList.Where([EXPRESSION]).Take(5);
或
var firstFiveArrivals = myList.Where([EXPRESSION]).Take(5).OrderBy([ORDER EXPR]);
它会比 orderBy 变体更快,因为 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)
}
}
【讨论】:
dataGridView1.DataSource = (from S in EE.Stagaire
join F in EE.Filiere on
S.IdFiliere equals F.IdFiliere
where S.Nom.StartsWith("A")
select new
{
ID=S.Id,
Name = S.Nom,
Prénon= S.Prenon,
Email=S.Email,
MoteDePass=S.MoteDePass,
Filiere = F.Filiere1
}).Take(1).ToList();
【讨论】: