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
Post a Comment