23

New to LINQ and not sure on the correct syntax for what I want to do.

I have a "Blocklist", an array or list (could be either) of bad codes that I don't want put into this new "keys" list that I am making

currently...

var keys = (from s in context.Keys
            where s.Code != "BadCode1"
            where s.Code != "BadCode2"
            where s.Code != "BadCode3"
            where s.Code != "BadCode4"
            where s.Code != "BadCode5"
            orderby s.Name
            select s).ToList<Keys>();

how would I trim it down to one line and have it read from the "blocklist" ? so more like...

var keys = (from s in context.Keys
            where s.Code != ANY OF THE VALUES FROM "BLOCKLIST"
            orderby s.Name
            select s).ToList<Keys>();

8 Answers8

25

Add it to an array and then use Contains:

var badCodes = new[] { "BadCode1", "BadCode2", "BadCode3", "BadCode4", "BadCode5"};

var keys = (from s in context.Keys
            where !badCodes.Contains(s.Code)
            orderby s.Name
            select s).ToList<Keys>();
Anderson Pimentel
  • 5,086
  • 2
  • 32
  • 54
21

All other answers are correct, but I'm personally a fan of this:

Assuming that you have a list of strings called blackList containing all strings you want to filter out.

var keys = context.Keys.Where(x => !blackList.Contains(x.Code))
    .OrderBy(x => x.Name)
    .ToList();

I just like the way this makes my code readable and easy to understand. But again, every other answer is correct.

12
var keys = (from s in context.Keys
    where !blackList.Contains(s.Code)
    orderby s.Name
    select s).ToList(); // do you really need the ToList?

an array or list (could be either)

If you're doing this in memory (linq to objects) then a HashSet would perform better than either an array or a list. If you're doing it in a database then it won't make any difference.

Also, do you really need it to be in a list? If you're going to loop through the results or otherwise do something for which IEnumerable<> or IQueryable<> will serve on its own, you're probably better leaving it out.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
7

Create a List<string> with all invalid values

List<string> sBlackList = new List<string>(){"BadCode1", "BadCode2", "BadCode3"};

and replace

where s.Code != ANY OF THE VALUES FROM "BLACKLIST" 

with

where !sBlackList.Contains(s.Code)
fubo
  • 44,811
  • 17
  • 103
  • 137
6

You can also use the Except Method similar to this:

var badCodes = new[] { "BadCode1", "BadCode2", "BadCode3", "BadCode4", "BadCode5"};

var blackList = context.Keys.Where(s => badCodes.Contains(s.Code));
var filteredKeys = context.Keys.Except(blackList);
S.Dav
  • 2,436
  • 16
  • 22
5

For detect intersection of any collections you can use .Contains() method. Its simply:

1) determine you blackList:

var blackList = new List<string> {"BadCode1", 
                                  "BadCode2", 
                                  "BadCode3", 
                                  "BadCode4",
                                  "BadCode5"};

2) filter the request by the intersection with the blackList (!blackList.Contains(s.Code)):

var keys = (from s in context.Keys
            where !blackList.Contains(s.Code)
            orderby s.Name
            select s).ToList<Keys>();
Nikita
  • 88
  • 4
1

You could have a list of codes of black list and check if it does not contain relevant codes

var keys = (from s in context.Keys
            where !blackList.Contains(s.Code)
            orderby s.Name
            select s).ToList<Keys>();
asdf_enel_hak
  • 7,474
  • 5
  • 42
  • 84
-1

Try to put all badcodes in a Hashset, and look for values not in "blacklist-hashest"

there is a good example here: https://stackoverflow.com/a/3944821/1117305

AJ AJ
  • 187
  • 2
  • 12
Nir
  • 601
  • 7
  • 21