在列表中找到“活动”项目,而不是“InActive”项目

时间:2016-07-14 17:05:29

标签: c# linq collections

我有一个清单

 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
            };

我需要在列表中找到状态为“活动”且未跟随“InActive”状态的项目。 例如:项目1 - 品牌“丰田”和状态“活动”后面是相同品牌的项目3,更晚的日期和“非活动”,但同一品牌的项目4具有“活动”状态,日期大于项目1和3并且没有同一品牌的“无效”状态。所以第4项有资格。

从上面的列表中,预期的结果是第4项和第8项。

我该怎么做?

4 个答案:

答案 0 :(得分:0)

试试这个:

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");

希望它有所帮助!

答案 1 :(得分:0)

这是最简单的方法:

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

每个品牌的最后一项只有在&#34; Active&#34;。

时才需要

答案 2 :(得分:0)

如果你只想要那些没有&#34; InActive&#34;在他们之后可以在字典中制作列表,并在你得到一个&#34; InActive&#34; status,然后在迭代完成后选择缓存中的所有值

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);

答案 3 :(得分:0)

你去了:

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不太适合处理序列元素关系。