C# 按多个变量条件筛选列表对象

C# 按多个变量条件筛选列表对象,c#,linq,C#,Linq,我有一个对象列表,需要从中提取值并保存到另一个列表中。如果存在重复的名称值,我需要选择与提供的生效日期相近的条目。我试着用一些if语句来实现这一点,但它很混乱,没有按预期运行。我可以想象使用LINQ有一种更简单的方法来实现这一点,但我不知道如何过滤掉这两种情况 这是我的对象类 class ExcelMessageRows { public string Name { get; set; } public string State { get; set; }

我有一个对象列表,需要从中提取值并保存到另一个列表中。如果存在重复的名称值,我需要选择与提供的生效日期相近的条目。我试着用一些if语句来实现这一点,但它很混乱,没有按预期运行。我可以想象使用LINQ有一种更简单的方法来实现这一点,但我不知道如何过滤掉这两种情况

这是我的对象类

class ExcelMessageRows
    {
        public string Name { get; set; }
        public string State { get; set; }
        public DateTime Date { get; set; }
        public string Message { get; set; }
    }

 //Here is the code using nested if statements -


           List<ExcelMessageRows> compareRows = new List<ExcelMessageRows>();
            compareRows.Add(new ExcelMessageRows { Name = "1", Date = DateTime.FromOADate(12/1/1997), Message = "a2" });
            compareRows.Add(new ExcelMessageRows { Name = "1", Date = DateTime.FromOADate(12/1/2005), Message = "a3" });
            compareRows.Add(new ExcelMessageRows { Name = "1", Date = DateTime.FromOADate(12/1/2015), Message = "a4" });
            compareRows.Add(new ExcelMessageRows { Name = "2", Date = DateTime.FromOADate(12/1/1997), Message = "a5" });
            compareRows.Add(new ExcelMessageRows { Name = "3", Date = DateTime.FromOADate(12/1/1998), Message = "a6" });
            compareRows.Add(new ExcelMessageRows { Name = "3", Date = DateTime.FromOADate(12/1/2006), Message = "a7" });
            compareRows.Add(new ExcelMessageRows { Name = "4", Date = DateTime.FromOADate(12/1/2015), Message = "a8" });
            compareRows.Add(new ExcelMessageRows { Name = "5", Date = DateTime.FromOADate(12/1/1998), Message = "a9" });
            compareRows.Add(new ExcelMessageRows { Name = "6", Date = DateTime.FromOADate(12/1/1999), Message = "a10" });
            compareRows.Add(new ExcelMessageRows { Name = "7", Date = DateTime.FromOADate(12/1/1997), Message = "a11" });
            compareRows.Add(new ExcelMessageRows { Name = "7", Date = DateTime.FromOADate(12/1/2014), Message = "a12" });
            compareRows.Add(new ExcelMessageRows { Name = "7", Date = DateTime.FromOADate(12/1/2016), Message = "a13" });

            //SETTING AN EFFECTIVE DATE AND STATE
            DateTime effectiveDate = DateTime.Now;
            //FINAL LIST OF MESSAGES
            List<string> decMessages = new List<string>();

            int previousRow = 1;

            compareRows.OrderBy(x => x.Name); 

            foreach (ExcelMessageRows mRows in compareRows)
            {                
                if (mRows.Name.Equals(compareRows[previousRow - 1].Name))
                {
                    if (effectiveDate > mRows.Date 
                        && effectiveDate > compareRows[previousRow - 1].Date)
                    { 
                        decMessages.Add(mRows.Message);
                    }

                    if (effectiveDate < mRows.Date
                        && effectiveDate > compareRows[previousRow - 1].Date)
                    {
                        decMessages.Add(compareRows[previousRow - 1].Message);
                    }
                }
                else
                {
                    decMessages.Add(compareRows[previousRow - 1].Message);
                }
                previousRow++;
            }

            foreach (string mes in decMessages)
                Console.WriteLine(mes);
        }```
类ExcelMessageRows
{
公共字符串名称{get;set;}
公共字符串状态{get;set;}
公共日期时间日期{get;set;}
公共字符串消息{get;set;}
}
//下面是使用嵌套if语句的代码-
List compareRows=新列表();
compareRows.Add(new ExcelMessageRows{Name=“1”,Date=DateTime.FromOADate(12/1/1997),Message=“a2”});
compareRows.Add(new ExcelMessageRows{Name=“1”,Date=DateTime.FromOADate(12/1/2005),Message=“a3”});
compareRows.Add(新的ExcelMessageRows{Name=“1”,Date=DateTime.FromOADate(12/1/2015),Message=“a4”});
compareRows.Add(new ExcelMessageRows{Name=“2”,Date=DateTime.FromOADate(12/1/1997),Message=“a5”});
compareRows.Add(new ExcelMessageRows{Name=“3”,Date=DateTime.FromOADate(12/1/1998),Message=“a6”});
compareRows.Add(new ExcelMessageRows{Name=“3”,Date=DateTime.FromOADate(12/1/2006),Message=“a7”});
compareRows.Add(new ExcelMessageRows{Name=“4”,Date=DateTime.FromOADate(12/1/2015),Message=“a8”});
compareRows.Add(new ExcelMessageRows{Name=“5”,Date=DateTime.FromOADate(12/1/1998),Message=“a9”});
compareRows.Add(new ExcelMessageRows{Name=“6”,Date=DateTime.FromOADate(12/1/1999),Message=“a10”});
compareRows.Add(new ExcelMessageRows{Name=“7”,Date=DateTime.FromOADate(12/1/1997),Message=“a11”});
compareRows.Add(new ExcelMessageRows{Name=“7”,Date=DateTime.FromOADate(12/1/2014),Message=“a12”});
compareRows.Add(new ExcelMessageRows{Name=“7”,Date=DateTime.FromOADate(12/1/2016),Message=“a13”});
//设置生效日期和状态
DateTime effectiveDate=DateTime.Now;
//信息的最终列表
List decMessages=新列表();
int-previousRow=1;
compareRows.OrderBy(x=>x.Name);
foreach(ExcelMessageRows在compareRows中的行和行)
{                
if(mRows.Name.Equals(compareRows[previousRow-1].Name))
{
如果(生效日期>当前日期)
&&生效日期>比较器视图[previousRow-1]。日期)
{ 
decMessages.Add(mRows.Message);
}
如果(生效日期<当前日期
&&生效日期>比较器视图[previousRow-1]。日期)
{
添加(compareRows[previousRow-1].Message);
}
}
其他的
{
添加(compareRows[previousRow-1].Message);
}
previousRow++;
}
foreach(消息中的字符串mes)
控制台写入线(mes);
}```

此代码会将每个姓名最近的消息添加到列表中。始终谨慎使用linq。短代码并不意味着短的运行时复杂性

        var groups = compareRows.GroupBy(p => p.Name);
        var decMessages = new List<string>();
        foreach (var group in groups)
            decMessages.Add(group.OrderBy(p => Math.Abs(effectiveDate.Subtract(p.Date).TotalMilliseconds)).Last().Message);
var-groups=compareRows.GroupBy(p=>p.Name);
var decMessages=新列表();
foreach(组中的var组)
添加(group.OrderBy(p=>Math.Abs(effectiveDate.Subtract(p.Date.totalmillizes)).Last().Message);

您需要做的是按名称分组,以便您可以选择每个组中最近的一个:

var decMessages = compareRows.GroupBy(r => r.Name)
                             .Select(rg => rg.OrderBy(r => effectiveDate-r.Date).First().Message)
                             .ToList();

您的代码似乎与您描述的不一样—例如,它返回了
Name
“1”的所有三条消息,而不是最新消息。顺便说一句,请注意,
OrderBy
是一个LINQ方法,它返回一个新的
IEnumerable
,它不会对传入的
列表进行排序。另外,用于创建示例数据的代码也不起作用。谢谢!这真的很有帮助。我还在寻找那些有三个相同名称的行,以捕获生效日期之前的列表。所以如果有1998年、2005年和2018年的日期,生效日期是2018年。该名单将增加2005年。我需要获得更多使用LINQ的经验。再次感谢!