Remove items of list from another lists with criteria

C#.NetLinqList

C# Problem Overview


i have a list of writers.

public class Writers{	
	long WriterID { get;set; }
}

Also I have two lists of type Article.

public class Article{
	long ArticleID { get; set; }
	long WriterID { get; set; }
	//and others	
}

so the code i have is:

List<Article> ArticleList = GetList(1);
List<Article> AnotherArticleList = AnotherList(2);
List<Writers> listWriters = GetAllForbiddenWriters();

I want to remove those records from ArticleList, AnotherArticleList where WriterID matches from listWriters WriterID. How to do this in LINQ?

C# Solutions


Solution 1 - C#

If you've actually got a List<T>, I suggest you use List<T>.RemoveAll, after constructing a set of writer IDs:

HashSet<long> writerIds = new HashSet<long>(listWriters.Select(x => x.WriterID));

articleList.RemoveAll(x => writerIds.Contains(x.WriterId));
anotherArticleList.RemoveAll(x => writerIds.Contains(x.WriterId));

If you do want to use LINQ, you could use:

articleList = articleList.Where(x => !writerIds.Contains(x.WriterId))
                         .ToList();
anotherArticleList = anotherArticleList
                         .Where(x => !writerIds.Contains(x.WriterId))
                         .ToList();
                                  

Note that this changes the variable but doesn't modify the existing list - so if there are any other references to the same list, they won't see any changes. (Whereas RemoveAll modifies the existing list.)

Solution 2 - C#

articlesList.RemoveAll(a => listWriters.Exists(w => w.WriterID == a.WriterID));
anotherArticlesList.RemoveAll(a => listWriters.Exists(w => w.WriterID == a.WriterID));

Solution 3 - C#

You can use Except:

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();

Solution 4 - C#

I do not really see what is the difficulty you are facing...

Why don't you just filter/remove data from you lists using a simple for loop ? (Note that a foreach Loop will definitely NOT work if you iterate while editing/changing the iterated object)

for (int i = ArticleList.Count -1; i >= 0; i--)
{
    for (int j = 0; j < listWriters.Count; j++)
    {
        if (ArticleList[i].WriterId == listWriters[j].WriterID )
            ArticleList.RemoveAt(i);
    }            
}

The Backward iteration trick solves the "delete items while iterating" paradigm.

Solution 5 - C#

Just a design tip, your class should be called Writer (singular form), not Writers (plural). Each item in your list represents a single writer, correct?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondeveloperView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#bitxwiseView Answer on Stackoverflow
Solution 3 - C#estinamirView Answer on Stackoverflow
Solution 4 - C#Mehdi LAMRANIView Answer on Stackoverflow
Solution 5 - C#danijelsView Answer on Stackoverflow