如果存在重复元素,则选择具有特定属性的第一个元素,否则选择第一个元素。

3
例如,我有一个对象列表,其中包含以下属性。
{ ID: "1", STATUS: "INA" }
{ ID: "1", STATUS: "ACT" } 
{ ID: "2", STATUS: "INA" } 
{ ID: "2", STATUS: "BLO" }

现在我想按ID对它们进行分组,以减少重复项,但是当发现重复项时,我想要检查任何状态是否为ACT,如果是ACT,则选择此记录,但是如果没有ACT状态,则选择第一个重复出现的记录。在上面的示例中,我想要选择。
{ ID: "1", STATUS: "ACT" } //since it has ACT
{ ID: "2", STATUS: "INA" } //since it is first duplicate found

我知道第一步是什么。
var NoDup = from l in list.AsEnumerable()
                  group l by l.ID into c

但我不知道接下来该怎么做

4个回答

8
var q = list.GroupBy(x => x.ID)
            .Select(g => g.OrderByDescending(x => x.STATUS == "ACT").First());

首先按ID对数据进行分组,然后按照比较结果x.STATUS == "ACT"返回的bool对分组进行排序。True比False更高,所以使用了OrderByDescendingFirst确保仅获取每个重复组的第一条记录。由于OrderBy...是稳定排序,即使没有ACT状态,原始顺序也会保持不变。
另一种类似的方法可能更有效率:
var q = list.GroupBy(x => x.ID)
    .Select(g => g.Where(x => x.STATUS == "ACT").DefaultIfEmpty(g.First()).First());

如果重复组非常大,这种方法可能更有效,因为如果第一个已经是“STATUS ==“ ACT””,则整个组不需要按bool排序。

我喜欢这种方法 :) 如果列表非常大,性能如何?如果列表比ID、STATUS更复杂,排序会花费很长时间吗? - undefined
起初,我以为 First() 会出错,后来意识到在这种情况下不会。@Tim 给出了完美的答案。 - undefined
1
@Tim 我同意Piotr的观点,假设每个ID有10000条记录,那么使用OrderByDescending会不会导致速度变慢呢? - undefined
@IpsitGaur:但是我添加了另一种方法,如果重复的组非常大,可能更有效率。可读性仍然很好。 - undefined
是的,@TimSchmelter看起来很棒。 - undefined
显示剩余4条评论

3
var NoDup = from l in list.AsEnumerable()
                  group l by l.ID into c
                  select c.FirstOrDefault(x => x.STATUS == "ACT") ?? 
                               c.FirstOrDefault()

@TimSchmelter 已经处理好了!谢谢。 - undefined
@TimSchmelter那么在这种情况下我应该怎么办呢?撤销我的更改吗? - undefined

2
from l in list
group l by l.ID into c
select c.FirstOrDefault(i => i.STATUS == "ACT") ?? c.First()

0
可以按照以下方式完成。
List
  .GroupBy( iLine =>
            iLine.ID )
  .Select( iGroup =>
           iGroup .FirstOrDefault( jLine => jLine.Status == "ACK" ? ) ?? iGroup.First() );

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