Reputation: 979
I need to find objects common to two lists, based on a different property on the objects in each list (objects in one list have a targetId property, I need to find all objects where the targetId matches the Id of objects in the first list. Objects in both lists have a range of other distinct properties.
The first list will define the order for the matched objects - the actual order doesn't matter, so long as both lists are ordered the same. Example below [pseudocode] shows what I mean, where the second list is sorted by TargetId to match the Id order in the first list:
firstList = [{name: a, id:1}, {name: b, id:2}, {name: c, id:3}]
secondList = [{name: d, targetId: 2}, {name:e, targetId: 3}, {name: f, targetId: 1}]
sortedList = [{name: f, targetId: 1}, {name:d, targetId: 2}, {name: e, targetId: 3}]
I thought something like the below would work, but I'm getting a sequence contains no elements error, even though I know each object has a match in the other list. Have tried sorting in place with no success.
List<object> firstList; // objects have an Id
List<object> secondList; // objects have a TargetId property
List<object> sortedList = new List<object>(); // the new list to store matched objects
foreach (object o in firstList) {
sortedList.Add(secondList.Where(x => x.TargetId == o.Id).First()); // should only return one object, but First() just in case
}
foreach (object o in sortedList) {
//do something with the ordered list
}
Upvotes: 0
Views: 2496
Reputation: 102753
I suggest converting the first loop to a Linq statement. The way you have it set up looks vulnerable to a modified closure problem:
var sortedList = firstList.Select(o =>
secondList.First(x => x.TargetId == o.Id))
.ToList();
I'm not sure where the "sequence contains no elements" error could be coming from other than First()
-- are you sure there are no elements in firstList
that have no match in secondList
? The below would be a good double-check (FirstOrDefault
instead of First
, with a null check):
var sortedList = firstList.Select(o =>
secondList.FirstOrDefault(x => x.TargetId == o.Id))
.Where(item => item != null)
.ToList();
Upvotes: 3