Reputation: 464
I was curious as to the best way to combine properties from duplicate records in a list. For example:
var res = new List<MyObjList> {
new MyObj { Id = 1, Type = "Class", Current = "Math", New = "Science" },
new MyObj { Id = 2, Type = "Class", Current = "Math", New = "Science" },
new MyObj { Id = 1, Type = "Year", Current = "Freshman", New = "Sophomore" },
new MyObj { Id = 3, Type = "Year", Current = "Junior", New = "Senior" }
}
I'm looking for this result:
var res = new List<NewObj> {
new NewObj { Id = 1, Class = "Math", UpcomingYear = "Freshman" },
new NewObj { Id = 2, Class = "Math", UpcomingYear = null },
new NewObj { Id = 3, Class = null, UpcomingYear = "Senior" }
}
Failed attempt:
var newRes = res
.GroupBy(x => x.Id)
.Select(grp => new NewObj {
ItemId = grp.Key.Id,
Class = grp.Key.Type == "Class" ? grp.Key.Class : null,
UpcomingYear = grp.Key.Type == "Year" ? grp.Key.UpcomingYear : null
});
The thing I don't quite understand is how to join duplicates by ID and create a new object with conditional property values (or combine properties from each duplicate).
Edit: Updated result type/object
Edit2: Updated with failed attempts
Thanks!
Upvotes: 0
Views: 166
Reputation: 6864
How about...
const string ClassType = "Class";
const string YearType = "Year";
var newRes = res
.Where(r => r.Type == ClassType)
.Select(r => new
{
r.Id,
Class = r.Current,
UpcomingYear = res
.Where(r2 => r2.Id == r.Id && r2.Type == YearType)
.Select(r2 => r2.Current)
.FirstOrDefault()
})
.Union(res
.Where(r =>
r.Type != ClassType &&
!res.Any(r2 => r2.Id == r.Id && r2.Type == ClassType))
.Select(r => new
{
r.Id,
Class = default(string),
UpcomingYear = r.New
}));
foreach(var item in newRes)
{
Console.WriteLine($"{item.Id}, '{item.Class}', '{item.UpcomingYear}'");
}
OUTPUT:
1, 'Math', 'Freshman'
2, 'Math', ''
3, '', 'Senior'
Upvotes: 1
Reputation: 12695
Say you have a Person
class with 2 properties: FirstName
and LastName
.
And you have a list of people, you want to combine those who have the same FirstName
and LastName
(i.e. remove duplicates).
You could use LINQ's GroupBy
method, like the following example:
List<Person> people = new List<Person> {
new Person
{
FirstName = "Arad",
LastName = "Aral"
},
new Person
{
FirstName = "Arad",
LastName = "Aral"
}
};
List<Person> duplicatesRemoved = people.GroupBy(p => p.FirstName + p.LastName).Select(g => g.First()).ToList();
Now, our new list duplicatesRemoved
is as follows:
List<Person> people = new List<Person> {
new Person
{
FirstName = "Arad",
LastName = "Aral"
}
};
Upvotes: 0