简体   繁体   中英

Remove specific items from list of objects

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?

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> .

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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM