在列表中查找“活动”项目,后面不跟“非活动”项目

本文关键字:项目 非活动 列表 活动 查找 | 更新日期: 2023-09-27 17:57:09

>我有一个列表

 public class CarRent
    {
        public string Brand { get; set; }
        public string Status { get; set; }
        public DateTime Date { get; set; }
    }
  var mylist = new List<CarRent>() {
                new CarRent() { Brand = "Toyota",Date=DateTime.Parse( "1/10/14"),Status="Active" },//1
                new CarRent() { Brand = "Honda",Date=DateTime.Parse( "5/3/14"),Status="Active" },//2
                new CarRent() { Brand = "Toyota",Date=DateTime.Parse( "6/28/14"),Status="InActive" },//3
                new CarRent() { Brand = "Toyota",Date=DateTime.Parse( "12/12/14"),Status="Active" },//4
                new CarRent() { Brand = "Honda",Date=DateTime.Parse( "12/14/14"),Status="InActive" },//5
                new CarRent() { Brand = "Ford",Date=DateTime.Parse( "3/22/15"),Status="Active" },//6
                new CarRent() { Brand = "Ford",Date=DateTime.Parse( "12/12/15"),Status="InActive" },//7
                 new CarRent() { Brand = "Ford",Date=DateTime.Parse( "6/15/16"),Status="Active" },//8
            };

我需要在列表中找到状态为"活动"而不是后跟"非活动"状态的项目。例如:商品 1 - 品牌"丰田"且状态为"在售"后跟相同品牌的商品 3、较晚的日期和"非在售",但同一品牌的商品 4 的状态为"在售"且日期大于商品 1 和 3,并且没有同一品牌的"非在售"状态。因此,第 4 项符合条件。

从上述列表中,预期结果是项目4和项目8。

我该怎么做?

在列表中查找“活动”项目,后面不跟“非活动”项目

如果您只希望处于活动状态且后面没有"InActive"的项目可以在字典中创建列表,并在获得"InActive"状态时清除,然后在完成迭代时选择缓存中的所有值

var cache = new Dictionary<string,List<CarRent>>();
for(int i=0; i<myList.Count; i++)
{
    var curr = myList[i];
    if(!cache.ContainsKey(curr.Brand))
    {
        cache[curr.Brand]=new List<CarRent>();
    }
    if(curr.Status == "InActive")
        cache[curr.Brand].Clear();
    else if(curr.Status == "Active")
        cache[curr.Brand].Add(curr);
}
var results = cache.Values.SelectMany(a=>a);

这是最简单的方法:

var results = mylist.GroupBy(x => x.Brand)
                .Select(x => x.LastOrDefault())
                .Where(x => x.Status == "Active").ToList();

仅当每个品牌的最后一项处于"活动"状态时,您才需要它。

你去吧:

var result =
    (from rent in mylist
     group rent by rent.Brand into brandRents
     let lastInactive = brandRents
        .Where(r => r.Status == "InActive")
        .DefaultIfEmpty()
        .Aggregate((rent1, rent2) => rent2.Date > rent1.Date ? rent2 : rent1)
     from rent in brandRents
     where rent.Status == "Active" && 
        (lastInactive == null || rent.Date > lastInactive.Date)
     select rent).ToList();

您可以按品牌对列表进行分组,然后为每个组找到最新的非活动元素(如果有),并选择其后的所有活动元素。

它的功能可能看起来很复杂,但 LINQ 不太适合处理序列元素关系。

试试这个:

var filteredList = mylist
    .OrderBy(item => iten.Date)
    .GroupBy(item => item.Brand)
    .SelectMany(itemsGroup => itemsGroup.Where((item, index) => item.Status == "Active" &&
        mylist.ElementAtOrDefault(index + 1)?.Status != "InActive");

希望对您有所帮助!