【问题标题】:Group by on IEnumerable<DataRow>按 IEnumerable<DataRow> 分组
【发布时间】:2012-07-31 08:25:06
【问题描述】:

我有一个 DataRow 对象的集合。我应该根据“URL_Link”列选择不同的行。在this post 之后,我想出了以下代码。
是否可以将其应用于 DataRow 集合?

IEnumerable<DataRow> results = GetData();  
results.GroupBy(row => row.Field<string>("URL_Link")).Select(grp => grp.First());

语法正确,但不能解决问题。它不会删除重复的行。我做错了什么?

【问题讨论】:

    标签: c# linq group-by datarow


    【解决方案1】:

    除了没有将结果集重新分配给result 变量的小错误。

    如果您实际上应该收到不同的值,我个人觉得使用不同的值要清楚得多。在这种情况下使用 Groupby 并不是很清楚,如果要返回整行,请查看下面的第一个示例,否则请查看第二个示例。

        class Program
        {
            static DataTable GetData()
            {
                DataTable table = new DataTable();
                table.Columns.Add("Visits", typeof(int));
                table.Columns.Add("URL_Link", typeof(string));
    
                table.Rows.Add(57, "yahoo.com");
                table.Rows.Add(130, "google.com");
                table.Rows.Add(92, "google.com");
                table.Rows.Add(25, "home.live.com");
                table.Rows.Add(30, "stackoverflow.com");
                table.Rows.Add(1, "stackoverflow.com");
                table.Rows.Add(7, "mysite.org");
                return table;
        }
    
        static void Main(string[] args)
        {
            var res = GetData()
                      .AsEnumerable()
                      .GroupBy(row => row.Field<string>("URL_Link"))
                      .Select(grp => grp.First());
    
            foreach (var item in res)
            {
                string text = "";
                foreach (var clm in item.ItemArray)
                    text += string.Format("{0}\t", clm);
    
                Console.WriteLine(text);
            }
            Console.ReadLine();
        }
    }
    

    这或多或少正是您已经提供的。首先,您没有重新分配变量。然后你应该从 ItemArray 到达你的字段。您会看到上面的示例,它给出了以下输出:

    57    yahoo.com
    130   google.com
    25    home.live.com
    30    stackoverflow.com
    7     mysite.com
    

    请记住,您可能必须指定 Select、Orderby 和 Where 子句,具体取决于您是否需要返回这些行中的特定行(即访问次数最多的重复行)。

    如果URL_Link 是您需要或想要从不同结果返回的唯一字段,则此示例清晰明了。它只需要选择你不想要的字段,然后区分它。

        static void Main(string[] args)
        {
            var res = GetData()
                        .AsEnumerable()
                        .Select(d=>d.Field<string>("URL_Link"))
                        .Distinct();
    
            foreach (var item in res)
                Console.WriteLine(item.ToString());  
    
            Console.ReadLine();
        }
    

    【讨论】:

    • Distinct() 也是我最初的想法,但它只返回不同的值(列)而不是行,不是吗?
    • Distinct() 使用IEqualityComparer&lt;T&gt; 接口来确定哪些项目是相似的。您可以制作自己的实现,并通过“Distinct()”调用来提供它。这样你就可以在完整的数据集上调用 Distinct() 并取回你的完整行,仍然只比较“URL_Link”。
    • @abatishchev 好的,没错。嗯,他在正确的轨道上。我编辑回复。
    【解决方案2】:

    您的 LINQ 操作的返回没有被分配给任何东西:

    IEnumerable<DataRow> results = GetData();  
    results = results.GroupBy(row => row.Field<string>("URL_Link")).Select(grp => grp.First());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多