Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
609 views
in Technique[技术] by (71.8m points)

generics - C# List<object>.RemoveAll() - How to remove a subset of the list?

I have a 2 classes feeds_Auto and Product with multiple matching properties. For this particular problem, the AutoID is the only field I need to use.

I have a List<FeedsAuto> with several hundred unique entries. I have a small List<Product> with 10, 20 unique entries. I now want to remove all items in the small list from the large list.

How do I use RemoveAll({lambda expression}) to accomplish this? All of the examples I have found depend on the generic list being of simple types (strings, ints, etc).

private static int DoInserts(ref List<Model.feeds_Auto> source, ref List<Model.Product> target, Guid companyID)
{
    List<Model.Product> newProductList = new List<Model.Product>();
    List<Model.Product> dropSourceList = new List<Model.Product>();


    using (var db = Helpers.GetProdDB())
    {
        foreach (var src in source)
        {
            var tgt = target.Where(a => a.alternateProductID == src.AutoID && a.LastFeedUpdate < src.DateModified).FirstOrDefault();
            if (tgt == null)
            {
                newProductList.Add(new Model.Product{...});
                dropSourceList.Add(src);
            }
        }
        db.SaveChanges();

        if (dropSourceList.Count > 0)
        {
            source.RemoveAll(????);
        }
    }
}

To do this in a loop is not difficult:

foreach (var drop in dropSourceList)
{
    source.RemoveAll(a => a.AutoID == drop.AutoID);
}

It just does not make sense (to me) to loop on a set to call RemoveAll for one item in each pass.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use Any to simplify

source.RemoveAll(a => dropSourceList.Any(b => a.AutoID == b.AutoID));

You can reduce the looping by creating a HashSet of ID's first:

var toRemove = new HashSet<int>(dropSourceList.ConvertAll(a => a.AutoID));

source.RemoveAll(a => toRemove.Contains(a.AutoID));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...