繁体   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