【问题标题】:How to get same results from select as foreach when using GroupBy()使用 GroupBy() 时如何从 select 中获得与 foreach 相同的结果
【发布时间】:2019-04-06 01:14:55
【问题描述】:

我希望能够获得与在使用 select 方法和匿名方法时在分组上使用 foreach 可以获得的相同结果。

    public class ExportData
    {
        public int Id { get; set; }

        public string Colour { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public int Money { get; set; }
    }

    public class ExportDataDictionary
    {
        public IDictionary<string, object> ColumnData { get; set; } = new Dictionary<string, object>();
    }

以上面的两个类为例。

我创建了一些数据..

        var dataCollection = new List<ExportData>
        {
            new ExportData { Name = "Name1", Age = 1, Colour = "Blue", Id = 1, Money = 10 },
            new ExportData { Name = "Name1", Age = 2, Colour = "Red", Id = 2, Money = 20 },
            new ExportData { Name = "Name1", Age = 2, Colour = "Green", Id = 3, Money = 30 },
            new ExportData { Name = "Name2", Age = 1, Colour = "Yellow", Id = 4, Money = 40 },
            new ExportData { Name = "Name3", Age = 2, Colour = "Blue", Id = 5, Money = 50 },
            new ExportData { Name = "Name4", Age = 3, Colour = "Blue", Id = 6, Money = 10 }
        };

接下来,我将这些数据按以下两个属性进行分组。

 var dataGrouping = dataCollection.GroupBy(g => new { g.Name, g.Age });

然后我创建一个 ExportDataDictionaries 列表并遍历分组中的每个组,每次创建一个新的 ExportDataDictionary 并将两个键都添加到字典中。

        var data = new List<ExportDataDictionary>();

        foreach (var grouping in dataGrouping)
        {
            var datadictionary = new ExportDataDictionary();

            datadictionary.ColumnData.Add("NAME", grouping.Key.Name);
            datadictionary.ColumnData.Add("AGE", grouping.Key.Age);
            data.Add(datadictionary);
        }

结果是 5 个 ExportDataDictionaries 的集合,每个 2 列包含对应于每个分组的键对。

我尝试用 Select 方法达到同样的效果如下所示。

        var data2 = new List<ExportDataDictionary>();

        var mydata = dataGrouping.Select(d => 
        {
            var datadictionary = new ExportDataDictionary();
            datadictionary.ColumnData.Add("NAME", d.Key.Name);
            datadictionary.ColumnData.Add("AGE", d.Key.Age);
            data2.Add(datadictionary);
            return data2;
        });

结果的类型:

mydata = {System.Linq.Enumerable.WhereSelectEnumerableIterator<System.Linq.IGrouping<<>f__AnonymousType0<string, int>, ConsoleApp2.Program.ExportData>, System.Collections.Generic.List<ConsoleApp2.Program.ExportDataDictionary>>}

它包含 5 个项目,每个项目包含 10 个字典。我期望的 5 个字典的值与使用 foreach 时的值相同,但每个字典都有 2 个副本。我相信这一定是因为它正在为分组中使用的两个键创建字典。所以,我想知道如何只为其中一个键或集合中的每个组执行此操作?

要求mydata应该包含与data变量中foreach获得的结果相同的结果

非常感谢任何帮助:)

【问题讨论】:

    标签: c# linq select foreach group-by


    【解决方案1】:

    只需在最后一条语句的末尾添加.ToList() 删除data2.Add(datadictionary); 语句并只返回数据字典return datadictionary; 像这样

    var mydata = dataGrouping.Select(d =>
            {
                var datadictionary = new ExportDataDictionary();
                datadictionary.ColumnData.Add("NAME", d.Key.Name);
                datadictionary.ColumnData.Add("AGE", d.Key.Age);
    
                return datadictionary;
            }).ToList();
    

    我已经运行了你的代码并检查并发现mydata 包含 5 个项目,每个项目包含 2 个 ColumnData 成员。

    其实你的Linq查询只有在你调用.ToList()函数时才会执行

    【讨论】:

    • 感谢您的帮助,不幸的是它不会产生与 foreach 相同的结果。您是正确的,因为 mydata 将包含 5 个项目,每个项目都有 5 个字典,但这不是我想要的。我只想要 5 个有 2 列的字典。有人确实发布了一个解决方案,但由于某种原因,他们的帖子很快就被删除了——我需要的是返回 datadictionary 而不是将它添加到 data2 并返回它!不过再次感谢-感谢您的帮助;)
    • 我已经按照要求修改了答案。
    猜你喜欢
    • 1970-01-01
    • 2018-10-24
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 2021-07-19
    • 2021-05-12
    相关资源
    最近更新 更多