C# 从列表中删除3个最早的元素<&燃气轮机;在C中#

C# 从列表中删除3个最早的元素<&燃气轮机;在C中#,c#,linq,C#,Linq,假设我有一个对象: public class CustomObj { DateTime Date { get; set; } String Name { get; set; } } 那么假设我有一个包含20个不同元素的列表 var stuff = new List<CustomObj> { { Date = DateTime.Now, Name = "Joe" }, { Date = DateTime.Now.AddDays(1), Name = "

假设我有一个对象:

public class CustomObj
{
    DateTime Date { get; set; }
    String Name { get; set; }
}
那么假设我有一个包含20个不同元素的列表

var stuff = new List<CustomObj>
{
    { Date = DateTime.Now, Name = "Joe" },
    { Date = DateTime.Now.AddDays(1), Name = "Joe2" },
    { Date = DateTime.Now.AddDays(2), Name = "Joe3" },
    { Date = DateTime.Now.AddDays(3), Name = "Joe4" },
    { Date = DateTime.Now.AddDays(4), Name = "Joe5" },
    { Date = DateTime.Now.AddDays(5), Name = "Joe6" },
    { Date = DateTime.Now.AddDays(6), Name = "Joe7" },
    { Date = DateTime.Now.AddDays(7), Name = "Joe8" },
    { Date = DateTime.Now.AddDays(8), Name = "Joe9" },
    { Date = DateTime.Now.AddDays(9), Name = "Joe10" },
    { Date = DateTime.Now.AddDays(10), Name = "Joe11" }
}

如果您的列表已排序,您可以简单地使用以下方法:


如果您只需要列举项目,这将起作用:

stuff.OrderBy(item => item.Date).Skip(3);
如果您确实希望它以列表形式出现,则必须在之后调用
.ToList()

stuff = stuff.OrderBy(item => item.Date).Skip(3).ToList();

如果您愿意用新列表替换此列表,您可以尝试以下方法:

stuff = stuff.OrderBy( c => c.Date).Skip(3).ToList();
另一方面,如果您需要
stuff
保持相同的
List
实例,则可以对其进行排序,然后按索引删除一个范围:

stuff.Sort(...);
stuff.RemoveRange(0, 3);

到目前为止,所有其他答案都依赖于对列表进行排序,如果尚未对列表进行排序,则这是一个O(n logn)操作

这是一个O(n)的解,虽然有一个可怕的常数因子。它使用from-如果需要,您可以轻松地在自己的代码中重写它,甚至让它直接返回索引而不是值(并使用
RemoveAt
而不是
Remove

//列表的计数部分是以
//少于3个元素
对于(int i=0;i<3&&list.Count>0;i++)
{
var oldest=list.MinBy(x=>x.Date);
删除(最旧的);
}

当然,您可以更高效地编写此代码,以便在列表的一次传递中找到最早的三个元素,但代码将更为复杂,导致出错的可能性更大。以上内容在O(n)中应该可以很好地工作,即使当你想在列表中浏览6次时它并不优雅:)

应该先排序,然后我们删除最后3如果你反复浏览列表删除项目,请确保使用for而不是foreach。如果“oldest”表示“first in”,最简单的解决方案应该是“先进先出”方法:使用一个
队列
。很好的问题,很容易理解用例,让我作为一个读者很容易找到正确的答案。感谢你询问的方式。它不会删除项目,只是跳过它们,并对返回值做什么?他可能想做一个.ToList()之后。它不会从源列表中删除项目,但OP可以将返回值分配给其他对象,例如调用ToList,然后重新分配给
stuff
变量。True。这不是最有效的方法,但它是最干净的。该死的,我的项目没有日期…:|
const int cToRemove = 3;

var top3 = (from c in stuff
        orderby c.Date ascending
        select c).Take(cToRemove);
stuff = stuff.OrderBy( c => c.Date).Skip(3).ToList();
stuff.Sort(...);
stuff.RemoveRange(0, 3);
// The list.Count part is in case the list starts off with
// fewer than 3 elements
for (int i = 0; i < 3 && list.Count > 0; i++)
{
    var oldest = list.MinBy(x => x.Date);
    list.Remove(oldest);
}