5

我有一系列列表:

List<foo> spamSpamAndSpam;
List<foo> spamSpamSpamSausageEggsAndSpam;
List<foo> spamSpamSpamSausageEggsBaconAndSpam;
List<foo> spamSpamSpamSpamSpamWithoutSpam;
List<foo> spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam;

我还在以下属性中寻找一系列值foo

List<string> Brian= new List<string>();
Brian.Add("Always");
Brian.Add("Look");
Brian.Add("On");
Brian.Add("The");
Brian.Add("Bright");
Brian.Add("Side");
Brian.Add("Of");
Brian.Add("Life");

我正在捕获对所有foo'ses 的引用,其中给定属性(例如,bar)具有包含在后一个列表中的值。我这样做是这样的:

func<foo, bool> deadParrot = x => Brian.Contains(x.bar);

IEnumerable<foo> okLumberjacks = spamSpamAndSpam.Where(deadParrot);
okLumberjacks = okLumberjacks.Concat(
    spamSpamSpamSpamSausageEggsAndSpam.Where(deadParrot));

// And so on, concatenating the results of Where() from every list of <foo>.

我需要每一个foo与过滤函数匹配的函数,IEnumerable<foo>以便我可以一次性调用所有函数中的一个方法,如下所示:

foreach (foo incontinentRunner in okLumberjacks)
{
    incontinentRunner.SillyWalk();
}

所以我的问题是......有没有办法收集一个集合foo中的每一个而不必诉诸于:

ni = ni.Concat(someList.Where(filter));

我的意思是,有没有更优雅的方法可以用 Linq 做这样的事情?我正在寻找类似的东西:

okLumberjacks = spamSpamAndSpam.
    And(spamSpamSpamSausageEggsAndSpam).
    And(spamSpamSpamSausageEggsBaconAndSpam) /* etc */ .Where(deadParrot);

甚至更好:

okLumberjacks = spanishInquisition.Where(deadParrot);
// Where the type of spanishInquisition is List<List<foo>>.

我不想修改原始列表,foo因为我需要它们,因为它们用于稍后在代码中的另一个操作。

4

3 回答 3

5

创建一个列表列表,然后将其展平:

List<List<foo>> lists = new List<List<foo>>()
{
    spamSpamAndSpam,
    spamSpamSpamSausageEggsAndSpam,
    //etc.
};

IEnumerable<foo> items = lists.SelectMany(item => item);
//do stuff with items.
于 2013-06-25T21:16:09.553 回答
2

我能想到的最好的是:

var everything = spam1.Concat(spam2).Concat(spam3);
var itemsIWant = everything.Where(x => Brian.Contains(x));
于 2013-06-25T21:22:18.980 回答
1

Union() 是否解决了您的问题?

        List<foo> spamSpamAndSpam;
        List<foo> spamSpamSpamSausageEggsAndSpam;
        List<foo> spamSpamSpamSausageEggsBaconAndSpam;
        List<foo> spamSpamSpamSpamSpamWithoutSpam;
        List<foo> spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam;

        var x = spamSpamAndSpam
            .Union(spamSpamSpamSausageEggsAndSpam)
            .Union(spamSpamSpamSausageEggsBaconAndSpam)
            .Union(spamSpamSpamSausageEggsBaconAndSpam)
            .Union(spamSpamSpamSpamSpamWithoutSpam)
            .Union(spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam)
            .Where(x => ..... );

注意:正如正确指出的那样,Union从返回集中排除重复项。这与Concat方法的行为不同,后者返回输入序列中的所有元素,包括重复项。由于不需要重复排除,因此 Concat 可能更好

于 2013-06-25T21:27:42.050 回答