Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Linq to remove from set where key exists in other set?

Tags:

c#

linq

What is the proper way to do set subtraction using Linq? I have a List of 8000+ banks where I want to remove a portion of those based on the routing number. The portion is in another List and routing number is the key property to both. Here is a simplification:

public class Bank
{
    public string RoutingNumber { get; set; }
    public string Name { get; set; }
}

var removeThese = new List<string>() { "111", "444", "777" };

var banks = new List<Bank>()
{
    new Bank() { RoutingNumber = "111", Name = "First Federal" },
    new Bank() { RoutingNumber = "222", Name = "Second Federal" },
    new Bank() { RoutingNumber = "333", Name = "Third Federal" },
    new Bank() { RoutingNumber = "444", Name = "Fourth Federal" },
    new Bank() { RoutingNumber = "555", Name = "Fifth Federal" },
    new Bank() { RoutingNumber = "666", Name = "Sixth Federal" },
    new Bank() { RoutingNumber = "777", Name = "Seventh Federal" },
    new Bank() { RoutingNumber = "888", Name = "Eight Federal" },
    new Bank() { RoutingNumber = "999", Name = "Ninth Federal" },
};

var query = banks.Remove(banks.Where(x => removeThese.Contains(x.RoutingNumber)));
like image 966
Robert Kerr Avatar asked Sep 25 '13 09:09

Robert Kerr


1 Answers

This should do the trick:

var toRemove = banks.Where(x => removeThese.Contains(x.RoutingNumber)).ToList();
var query = banks.RemoveAll(x => toRemove.Contains(x));

The first step is to make sure that you don't have to re-run that first query over and over again, whenever banks changes.

This should work too:

var query = banks.Except(toRemove);

as your second line.

EDIT

Tim Schmelter pointed out that for Except to work, you need to override Equals and GetHashCode.

So you could implement it like so:

public override string ToString()
{
   ... any serialization will do, for instance JSON or CSV or XML ...
   ... OR any serialization that identifies the object quickly, such as:
   return "Bank: " + this.RoutingNumber;
}


public override bool Equals(System.Object obj)
{
    return ((obj is Bank) && (this.ToString().Equals(obj.ToString()));
}


public override int GetHashCode()
{
    return this.ToString().GetHashCode();
}
like image 94
Roy Dictus Avatar answered Oct 27 '22 08:10

Roy Dictus