使用PLINQ处理具有嵌套循环的列表

时间:2012-09-21 14:28:18

标签: c# .net linq loops plinq

我有一个这样的循环:

        this.results = new List<Tuple<int, IEnumerable<Thing>>>();

        var utcNow = DateTime.UtcNow;
        var resultsLocker = new object();

        Parallel.ForEach(
            this.dataHelper.GetActiveIds(),
            id =>
            {
                var result = new Tuple<int, IEnumerable<Thing>>(
                    id,
                    this.dataHelper.GetThing(id, this.PossibleLastRunTime, utcNow));

                lock (resultsLocker)
                {
                    this.results.Add(result);
                }
            });

并使用this answer翻译成更紧凑和易懂的内容:

        this.results = this.dataHelper.GetActiveIds()
            .AsParallel()
            .Select(id => new Tuple<int, IEnumerable<Thing>>(
                id,
                this.dataHelper.GetThing(id, this.PossibleLastRunTime, utcNow)))
            .ToList();

现在我有一个更复杂的嵌套循环:

        var measuresLocker = new object();
        var measures = new List<Tuple<int, object, object>>();

        Parallel.ForEach(
            this.results,
            result =>
            {
                foreach (var measuredValue in result.Item2.Select(destination =>
                    new Tuple<int, object, object>(
                        result.Item1,
                        destination.Message,
                        destination.DestinationName)))
                {
                    lock (measuresLocker)
                    {
                        measures.Add(measuredValue);
                    }
                }
            });

我想做类似的事情,但我对这段代码感到困惑:

        measures = this.results
            .AsParallel()
            .Select(result => result.Item2.Select(destination =>
                new Tuple<int, object, object>(
                    result.Item1,
                    destination.Message,
                    destination.DestinationName)).ToList()).ToList();

我似乎得到了一个列表列表,我根据原始代码只想要一个列表。使用LINQ可以非常简洁地完成吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:3)

要将列表列表展平为单个列表,请使用SelectMany()而不是Select()。

   measures = this.results
        .AsParallel()
        .SelectMany(result => result.Item2.Select(destination =>
            new Tuple<int, object, object>(
                result.Item1,
                destination.Message,
                destination.DestinationName)).ToList()).ToList();