如果有任何重复项,请选择具有特定属性的第一个元素,否则选择第一个元素



例如,我有一个对象列表,其中包含这些属性

{ 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

但我不知道下一步该怎么做

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

因此,首先按 ID 分组,然后按比较x.STATUS == "ACT"返回的bool对组进行排序。真比假"高",这就是我使用 OrderByDescending 的原因. First确保我只获得每个重复组的第一条记录。由于OrderBy...具有稳定的排序,因此即使没有 ACT 状态,也会保持原始顺序。


另一种可能更有效的类似方法是:

var q = list.GroupBy(x => x.ID)
    .Select(g => g.Where(x => x.STATUS == "ACT").DefaultIfEmpty(g.First()).First());
如果

复制组非常大,这可能会更有效,因为如果第一个组已经STATUS == "ACT",则不需要按bool对整个组进行排序。

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

可以按如下方式完成。

List
  .GroupBy( iLine =>
            iLine.ID )
  .Select( iGroup =>
           iGroup .FirstOrDefault( jLine => jLine.Status == "ACK" ? ) ?? iGroup.First() );

最新更新