簡體   English   中英

當排除列表為空時,從Linq查詢中排除所有結果的結果

[英]Exclude results from Linq query excluding everything when exclude list is empty

我有以下代碼:

        public IList<Tweet> Match(IEnumerable<Tweet> tweetStream, IList<string> match, IList<string> exclude)
    {
        var tweets = from f in tweetStream
                     from m in match
                     where f.Text.ToLowerInvariant().Contains(m) 
                     select f;

        var final = from f in tweets
                    from e in exclude
                    where !f.Text.ToLowerInvariant().Contains(e.ToLowerInvariant())
                    select f;

        return final.Distinct().ToList<Tweet>();
    }

我一直在構建尚未包含final結果集的測試,並且一直很高興地進行匹配。現在,如果IList<string>exclude為空,則所有項目均被刪除,我添加了exclude。

因此,此測試通過了:

        [TestMethod]
    public void Should_exclude_items_from_exclude_list()
    {
        IEnumerable<Tweet> twitterStream = new List<Tweet>
                                               {
                                                   new Tweet("I have a Mazda car"),
                                                   new Tweet("I have a ford"),
                                                   new Tweet("Mazda Rules"),
                                                   new Tweet("My Ford car is great"),
                                                   new Tweet("My renault is brill"),
                                                   new Tweet("Mazda cars are 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);            
    }

但是此測試現在失敗:

        [TestMethod]
    public void Should_match_items_either_mazda_or_car_but_no_duplicates()
    {
        IEnumerable<Tweet> twitterStream = new List<Tweet>
                                               {
                                                   new Tweet("I have a Mazda car"),
                                                   new Tweet("I have a ford"),
                                                   new Tweet("Mazda Rules"),
                                                   new Tweet("My Ford car is great"),
                                                   new Tweet("My renault is brill"),
                                                   new Tweet("Mazda cars are 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);
    }

我知道我缺少了一些非常簡單的東西,但是在盯着代碼一個小時之后,它卻沒有出現。

好吧,我知道為什么會失敗:這是這個子句:

from e in exclude

那將是一個空集合,因此沒有條目甚至可以打到where子句。

這是另一種方法:

var final = from f in tweets
            let lower = f.Text.ToLowerInvariant()
            where !exclude.Any(e => lower.Contains(e.ToLowerInvariant())
            select f;

盡管我也考慮了msarchet的方法,但是關於此方法的好處是它只對tweetStream一次評估-因此,即使從網絡中讀取tweetStream或造成其他tweetStream ,您也不必擔心。 在可能的情況下(並且方便),我嘗試避免多次評估LINQ流。

當然,您可以很輕松地使整個查詢成為一個查詢:

var tweets = from f in tweetStream
             let lower = f.Text.ToLowerInvariant()
             where match.Any(m => lower.Contains(m.ToLowerInvariant())
             where !exclude.Any(e => lower.Contains(e.ToLowerInvariant())
             select f;

老實說,我認為這樣更干凈:)

所以這是怎么回事:

var final = from f in tweets
            from e in exclude
            where !f.Text.ToLowerInvariant().Contains(e.ToLowerInvariant())
            select f;

由於第二個from為空,因此,如果我是對的,則不會評估該語句的其余部分,因此您的選擇永遠不會發生。

嘗試像這樣做

var excludeTheseTweet = from f in tweets
                        from e in exclude
                        where f.Text.ToLowerInvariant().Contains(e.ToLowerInvariant())
                        select f;

return tweets.Except(excludeTheseTweets).Distinct().ToList<Tweet>();

這樣一來,便會得到一系列推文列表(因此,如果沒有要排除的內容,它將一無所獲),然后將從原始列表中刪除這些項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM