Reputation: 97
For example I have a list of objects, with those properties
{ ID: "1", STATUS: "INA" }
{ ID: "1", STATUS: "ACT" }
{ ID: "2", STATUS: "INA" }
{ ID: "2", STATUS: "BLO" }
And now I want to group them by ID, to reduce duplicates, but when the duplicates are found I want to check if any of the statuses is ACT, if it is ACT i want to select this record, but if there's no ACT status I want to select first occurrence of the duplicate.
In example above I would want to select
{ ID: "1", STATUS: "ACT" } //since it has ACT
{ ID: "2", STATUS: "INA" } //since it is first duplicate found
I know that the first step would be
var NoDup = from l in list.AsEnumerable()
group l by l.ID into c
But I don't know what to do next
Upvotes: 3
Views: 1077
Reputation: 2927
var NoDup = from l in list.AsEnumerable()
group l by l.ID into c
select c.FirstOrDefault(x => x.STATUS == "ACT") ??
c.FirstOrDefault()
Upvotes: 3
Reputation: 460108
var q = list.GroupBy(x => x.ID)
.Select(g => g.OrderByDescending(x => x.STATUS == "ACT").First());
So first group-by the ID, then order the groups by the bool
that is returned from the comparison x.STATUS == "ACT"
. True is "higher" than false, that's why i used OrderByDescending
. First
ensures that i only get the first record of every duplicate-group. Since OrderBy...
has a stable sort the original order is maintained even if there is no ACT-status.
Another similar approach which might be little bit more efficient is:
var q = list.GroupBy(x => x.ID)
.Select(g => g.Where(x => x.STATUS == "ACT").DefaultIfEmpty(g.First()).First());
This could be more efficient if the duplicae-groups are very large because the whole group doesn't need to be ordered by the bool
if the first was already STATUS == "ACT"
.
Upvotes: 8
Reputation: 17605
It could be done as follows.
List
.GroupBy( iLine =>
iLine.ID )
.Select( iGroup =>
iGroup .FirstOrDefault( jLine => jLine.Status == "ACK" ? ) ?? iGroup.First() );
Upvotes: 0
Reputation: 7036
from l in list
group l by l.ID into c
select c.FirstOrDefault(i => i.STATUS == "ACT") ?? c.First()
Upvotes: 2