c# - Exclude results from Linq query excluding everything when exclude list is empty -


i have following code:

        public ilist<tweet> match(ienumerable<tweet> tweetstream, ilist<string> match, ilist<string> exclude)     {         var tweets = f in tweetstream                      m in match                      f.text.tolowerinvariant().contains(m)                       select f;          var final = f in tweets                     e in exclude                     !f.text.tolowerinvariant().contains(e.tolowerinvariant())                     select f;          return final.distinct().tolist<tweet>();     } 

i've been building tests haven't included final resultset , been matching happily i've added exclude if ilist<string>exclude empty items removed.

so test passes should:

        [testmethod]     public void should_exclude_items_from_exclude_list()     {         ienumerable<tweet> twitterstream = new list<tweet>                                                {                                                    new tweet("i have mazda car"),                                                    new tweet("i have ford"),                                                    new tweet("mazda rules"),                                                    new tweet("my ford car great"),                                                    new tweet("my renault brill"),                                                    new tweet("mazda cars great")                                                };         ilist<string> matches = new list<string>{"mazda","car"};         ilist<string> exclude = new list<string>{"ford"};          matcher target = new matcher();         ilist<tweet> actual = target.match(twitterstream, matches, exclude);          assert.areequal(3, actual.count);                 } 

but test fails:

        [testmethod]     public void should_match_items_either_mazda_or_car_but_no_duplicates()     {         ienumerable<tweet> twitterstream = new list<tweet>                                                {                                                    new tweet("i have mazda car"),                                                    new tweet("i have ford"),                                                    new tweet("mazda rules"),                                                    new tweet("my ford car great"),                                                    new tweet("my renault brill"),                                                    new tweet("mazda cars great")                                                };         ilist<string> matches = new list<string>{"mazda","car"};         ilist<string> exclude = new list<string>();          matcher target = new matcher();         ilist<tweet> actual = target.match(twitterstream, matches, exclude);          assert.areequal(4, actual.count);     } 

i know i'm missing simple after staring @ code hour not coming me.

well, know why it's failing: it's clause:

from e in exclude 

that's going empty collection, there no entries hit clause.

here's alternative approach:

var final = f in tweets             let lower = f.text.tolowerinvariant()             !exclude.any(e => lower.contains(e.tolowerinvariant())             select f; 

although considered msarchet's approach well, nice thing 1 ends evaluating tweetstream once - if reads network or else painful, don't need worry. possible (and convenient) try avoid evaluating linq streams more once.

of course, can make whole thing 1 query easily:

var tweets = f in tweetstream              let lower = f.text.tolowerinvariant()              match.any(m => lower.contains(m.tolowerinvariant())              !exclude.any(e => lower.contains(e.tolowerinvariant())              select f; 

i'd consider cleaner, honest :)


Comments

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -