Reputation: 13616
I have list of objects:
public class SDesc
{
public string sensorId { get; set; }
public string address { get; set; }
}
List<SDesc> desc = new List<SDesc>
{
new SDesc {sensorId = "1234", address = "Adams22"},
new SDesc {sensorId = "5555", address = "Hourton34"},
new SDesc {sensorId = "4444", address = "SaintsRoad55"},
new SDesc {sensorId = "1258", address = "BerryAve58"},
new SDesc {sensorId = "52486", address = "SaintsRoad2"},
new SDesc {sensorId = "12361", address = "TomassonRoad"}
}
And also I have IEnumarable of strings:
IEnumarable<string> sId = {"4444","52486","12361"};
from desc list I need to remove records where sensorsId property exists in sId list.
For example for case above the result I want to get is:
List<SDesc> desc = new List<SDesc>
{
new SDesc {sensorId = "1234", address = "Adams22"},
new SDesc {sensorId = "5555", address = "Hourton34"},
new SDesc {sensorId = "1258", address = "BerryAve58"},
}
Here what I tried:
desc.RemoveAll(obj => obj.sensorId == sId);
But it's not works properly because sID is IEnumarable type.
So my question is how to remove items from desc list where sensorsId property exists in sId list?
Upvotes: 1
Views: 96
Reputation: 34189
You can use .Contains()
LINQ method to check if a collection contains an item:
desc.RemoveAll(obj => sId.Contains(obj.sensorId));
However, it would lead to multiple enumeration of enumerable sId
. It's not a problem in this case since this enumerable is an array in this particular case.
Read more about "possible multiple enumeration":
- Handling warning for possible multiple enumeration of IEnumerable
- Resharper's example code for explaining "Possible multiple enumeration of IEnumerable"
I would recommend converting it to a collection to make sure you enumerate IEnumerable
only once.
As suggested by Evk in comments, it is better to use HashSet
so that .Contains
executes in O(1)
time:
List<SDesc> desc = new List<SDesc> {
new SDesc {sensorId = "1234", address = "Adams22"},
new SDesc {sensorId = "5555", address = "Hourton34"},
new SDesc {sensorId = "4444", address = "SaintsRoad55"},
new SDesc {sensorId = "1258", address = "BerryAve58"},
new SDesc {sensorId = "52486", address = "SaintsRoad2"},
new SDesc {sensorId = "12361", address = "TomassonRoad"}
};
IEnumarable<string> sId = {"4444","52486","12361"};
var sIdsSet = new HashSet(sId);
desc.RemoveAll(obj => sIdsSet.Contains(obj.sensorId));
Upvotes: 2
Reputation: 62488
You need to use Any
with it like:
desc.RemoveAll(obj => sId.Any(x=> x== obj.sensorId ));
As method name suggests it would check if any of the item in sId
matches with the item in desc
against sensorId
, it will remove those items from List<T>
.
Upvotes: 3