使用LINQ将特定的不同记录获取到列表中

4

我一直在使用这个:

return myListOfContacts.DistinctBy(e => e.Id).Where(e => e.CompanyId == companyId).ToList();

这会返回一个请求的去重列表。问题是,当记录是重复时,返回的记录是列表中的第一个。

例如,如果我的联系人中有以下联系人:

[Id - ContactId - Name - FlagIWantThisOne]

1 - 99 - John - true
2 - 56 - Mike - false
2 - 56 - Mike - true
3 - 13 - Dave - false

它返回3条记录:

John、Mike和Dave。

但我想要的是标记为true的那个“Mike”记录。

总之,如果记录重复,则列表应返回设置为true的记录并忽略其他记录。

我使用了 distinctBy,但它只返回列表中找到的第一个记录。

4个回答

4
你可以尝试以下方法:
myListOfContacts.GroupBy(e => e.Id)
                .Select(g => g.OrderByDescending(r => r.FlagIwantThisOne).First())
                .ToList();

逻辑如下:
按 Id 进行分组。然后,通过降序排序组 (true > false),并从每个组中取出第一个。

2

首先对列表进行排序应该有所帮助。此外,出于性能考虑,我会将where子句放在最前面:

return myListOfContacts.Where(e => e.CompanyId == companyId)
                       .OrderBy(e => e.Flag)
                       .DistinctBy(e => e.Id)
                       .ToList();

2

不要按照分组元素的顺序排序,这样时间复杂度为O(N*log(N)),你可以使用简单的O(N)搜索加上返回到原始逻辑的后备方案:

return myListOfContacts
    .Where(e => e.CompanyId == companyId)
    .GroupBy(e => e.Id, (key, elements) =>
        elements.FirstOrDefault(e => e.FlagIWantThisOne) ?? elements.First())                   .OrderBy(e => e.Flag)
    .ToList();

基本上,如果记录是重复的,则列表应返回设置为true的标志并忽略其他记录。

0

尝试反转列表:

return myListOfContacts
    .Reverse()
    .DistinctBy(e => e.Id)
    .Where(e => e.CompanyId == companyId)
    .ToList();

但我真的认为你应该避免重复记录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接