Combining lists but getting unique members
I have a bit of a special requirement when combining lists. I will try to illustrate with an example. Lets say I'm working with 2 lists of GamePlayer objects. GamePlayer has a property called LastGamePlayed. A unique GamePlayer is identified through the GamePlayer.ID property. Now I'd like to combine listA and listB into one list, and if a 开发者_如何转开发given player is present in both lists I'd like to keep the value from listA.
I can't just combine the lists and use a comparer because my uniqueness is based on ID, and if my comparer checks ID I will not have control over whether it picks the element of listA or listB. I need something like:
for each player in listB
{
if not listA.Contains(player)
{
listFinal.Add(player)
}
}
However, is there a more optimal way to do this instead of searching listA for each element in listB?
****EDIT****: Alternately, what if I wanted to choose which GamePlayer I keep based on the value of LastGamePlayed (instead of knowing that ListA takes precedence over ListB)? So I want a unique list of GamePlayer objects but for each player I want the GamePlayer object with the most recent LastGamePlayed? Basically I need a way to determine which object to keep when there are duplicate GamePlayers.
You should be able to use the linq enumerable extension Concat and Exept to achieve this.
listA.Concat(listB.Except(listA);
This will remove items in B that match A, and them add the result to A.
You will have to write an IEqualityComparer which compares by ID.
Documentation for theses methods can be found here:
MSDN Enumerable Extensions
IEqualityComparer documentation can be found here:
MSDN IEqualityComparer
Now that this has been clarified, the question is basically this:
- Combine all elements from list A and list B, and if there are any duplicates, keep the one with the newest
LastGamePlayed
.
I would do this with a grouping:
var players = from p in listA.Concat(listB)
group p by p.ID into g
select g.OrderByDescending(x => x.LastGamePlayed).First();
If performance is an issue, there are "faster" ways to write this, but I would start with this.
You can write an O(n log n) solution by building a set from list2 then overwriting (or inserting) items with list1, then converting that set back to a list.
If the lists are already sorted, you could do it O(n) by merging by hand.
精彩评论