如何在C#中获取列表的前N个元素?

如何在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

我想在我的项目中使用Linq查询公交车时刻表,这样我就可以随时得到接下来的5辆公交车的到达时间。如何将查询限制为前5个结果

更一般地说,如何在C#中获取列表的一部分?(在Python中,我将使用
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,谢谢您的回答。虽然您的代码可能会解决张贴的问题中的问题,但好的答案可以解释为什么您的解决方案有效。请考虑更新你的问题。