简体   繁体   中英

C# LINQ select from where value is not contained in array / list

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

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

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.

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.

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)

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

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

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

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

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