C# 使用linq删除重复列表对象

C# 使用linq删除重复列表对象,c#,linq,C#,Linq,我正在开发一个函数,该函数应该从列表对象中删除重复项。以下是要求: 如果Tradeline具有以下条件,则视为重复: 相同的帐号、帐户类型、日期,并且不是手动的 如果你发现了一些东西,那么只选择那些已经找到的 最新报告日期 如果报告日期相同,则比较(30,60,90)字段并选择在上述三个属性中具有较高值的贸易线 我在执行最后一点时遇到了困难。这是我的密码: public IEnumerable<Tradeline> DedupeTradeline(IEnumerable<

我正在开发一个函数,该函数应该从列表对象中删除重复项。以下是要求:

如果Tradeline具有以下条件,则视为重复:

  • 相同的帐号、帐户类型、日期,并且不是手动的
如果你发现了一些东西,那么只选择那些已经找到的

  • 最新报告日期
  • 如果报告日期相同,则比较(30,60,90)字段并选择在上述三个属性中具有较高值的贸易线
我在执行最后一点时遇到了困难。这是我的密码:

public IEnumerable<Tradeline> DedupeTradeline(IEnumerable<Tradeline> tradelines)
{
    //split tradeline into manual and non-manual    
    var tradelineDictionary = tradelines.GroupBy(x => x.Source == "MAN").ToDictionary(x => x.Key, x => x.ToList());
    //create list of non-manual tradeline for dedupe logic
    var nonManualTradelines = tradelineDictionary.Where(x => x.Key == false).Select(x => x.Value).FirstOrDefault();
    var manualTradelines = tradelineDictionary.Where(x => x.Key).Select(x => x.Value).FirstOrDefault();

    //check if same reported date is present for dedupe tradelines
    var duplicate = nonManualTradelines?.GroupBy(x => new
    {
        x.ReportedDate,
        x.Account,
        x.AcctType,
        x.Date
    }).Any(g => g.Count() > 1);

    IEnumerable<Tradeline> dedupe;
    if (duplicate != null && (bool) !duplicate)
    {
        //logic for dedupe tradeline if no same reported date
        dedupe = nonManualTradelines.GroupBy(x => new
            {
                x.Account,
                x.AcctType,
                x.Date
            })
            //in case of duplicate tradelines select one with the latest date reported
            .Select(x => x.OrderByDescending(o => o.ReportedDate).First());
    }
    else
    {
        //logic for dedupe tradeline if same reported date
        dedupe = nonManualTradelines?.GroupBy(x => new
            {
                x.ReportedDate,
                x.Account,
                x.AcctType,
                x.Date
            })
            .Select(); 
            // Stuck here not sure what to do
    }

    //append manual tradeline to the output of dedupe tradelines
    var response = manualTradelines != null ? (dedupe).Union(manualTradelines) : dedupe;

    return response;
}

您可以按最大
Late
x值降序排序。我将
字典
的特殊用法替换为两个类别的简单而高效的分离

public static class ObjectExt {
    public static int ToInt<T>(this T obj) => Convert.ToInt32(obj);    
}

public IEnumerable<Tradeline> DedupeTradeline(IEnumerable<Tradeline> tradelines) {
    //split tradeline into manual and non-manual    
    var nonManualTradelines = new List<Tradeline>();
    var manualTradelines = new List<Tradeline>();
    foreach (var t in tradelines) {
        if (t.Source == "MAN")
            manualTradelines.Add(t);
        else
            nonManualTradelines.Add(t);
    }

    IEnumerable<Tradeline> dedupe = nonManualTradelines.GroupBy(t => new {
                t.Account,
                t.AcctType,
                t.Date
            })
            //in case of duplicate tradelines select one with the latest date reported
            .Select(tg => tg.OrderByDescending(t => t.ReportedDate).ThenByDescending(t => Math.Max(t.Late90.ToInt(), Math.Max(t.Late60.ToInt(), t.Late30.ToInt()))).First());

    //append manual tradeline to the output of dedupe tradelines
    return dedupe.Union(manualTradelines);
}
公共静态类ObjectExt{
公共静态int ToInt(此T obj)=>转换为32(obj);
}
公共IEnumerable重复数据传输线(IEnumerable贸易线){
//将贸易线分为手动和非手动
var nonManualTradelines=新列表();
var manualTradelines=新列表();
foreach(交易线中的var t){
如果(t.Source==“MAN”)
手册贸易线。添加(t);
其他的
非手动贸易线。添加(t);
}
IEnumerable重复数据消除=非手动Radelines.GroupBy(t=>new{
t、 帐户,
t、 账户类型,
t、 日期
})
//如果存在重复的贸易线,请选择一个报告了最新日期的贸易线
.选择(tg=>tg.OrderByDescending(t=>t.ReportedDate)。然后选择(t=>Math.Max(t.Late90.ToInt(),Math.Max(t.Late60.ToInt(),t.Late30.ToInt()))。First();
//将手动贸易线附加到重复数据消除贸易线的输出
返回重复数据消除联合(manualTradelines);
}

贸易线是否可能具有较高的30但较低的60或90?在这种情况下,哪一个具有优先权?到目前为止,30/60/90具有相同的优先权。例如,一条贸易线的值为
9-9-9
,另一条贸易线的值为
10-0-0
。那么我们应该选择第二个。它只看较高的数字。如果它有9-9-9和0-0-10,它会选择第一个吗?还有,为什么这些
string
s?它将是第二个。逻辑是选择更高的值,无论其在30/60/90中的位置如何。这些是
string
s,因为我是从
XML
中读取它们的,为了简单起见,没有将其转换为
int
谢谢!尽管如此,30/60/90逻辑只有在确定的类似贸易线组中,报告日期也相同时才会发生。如果不是,则只选择最新报告日期贸易线。“我想你错过了这个逻辑。@Shaggy考虑一下排序-如果最新报告的日期没有重复项,它将排序到顶部。”。如果它有重复项,则顶部的重复组将按max Late*值排序。
public static class ObjectExt {
    public static int ToInt<T>(this T obj) => Convert.ToInt32(obj);    
}

public IEnumerable<Tradeline> DedupeTradeline(IEnumerable<Tradeline> tradelines) {
    //split tradeline into manual and non-manual    
    var nonManualTradelines = new List<Tradeline>();
    var manualTradelines = new List<Tradeline>();
    foreach (var t in tradelines) {
        if (t.Source == "MAN")
            manualTradelines.Add(t);
        else
            nonManualTradelines.Add(t);
    }

    IEnumerable<Tradeline> dedupe = nonManualTradelines.GroupBy(t => new {
                t.Account,
                t.AcctType,
                t.Date
            })
            //in case of duplicate tradelines select one with the latest date reported
            .Select(tg => tg.OrderByDescending(t => t.ReportedDate).ThenByDescending(t => Math.Max(t.Late90.ToInt(), Math.Max(t.Late60.ToInt(), t.Late30.ToInt()))).First());

    //append manual tradeline to the output of dedupe tradelines
    return dedupe.Union(manualTradelines);
}