具有重复ID的集合展平为一行

时间:2018-05-08 17:25:53

标签: c#

我有一个问题,我正试图将它压平成一行。

Example
ID      name         description  name2      Description2
555     newname      a descript
555                               name2      Description2name
543     onename      myname     

结果应该是什么样的。

Example final
ID      name         description  name2      Description2
555     newname      a descript   name2      Description2name 
543     onename      myname

基本上使用linq语句然后list.Add(addlist) 将列表添加到我的DTO后,我使用foreach循环。 不确定决赛如何组合起来产生最终结果如上例所示。

2 个答案:

答案 0 :(得分:3)

不确定它的表现如何,但它可以解决问题:)

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        var dataItems = new List<Data>
        {
            new Data { ID = 555, Name = "newname", Description = "a descript" },
            new Data { ID = 555, Name2 = "name2", Description2 = "Description2name" },
            new Data { ID = 543, Name = "onename", Description = "myname" },
        };

        var aggregate = dataItems
            .GroupBy(x => x.ID, x => x)
            .Select(g => g.Aggregate((current, next) =>
            {
                current.Description = current.Description ?? next.Description;
                current.Description2 = current.Description2 ?? next.Description2;
                current.Name = current.Name ?? next.Name;
                current.Name2 = current.Name2 ?? next.Name2;
                return current;
            }));

        foreach (var item in aggregate)
        {
            Console.WriteLine($"{item.ID}\t{item.Name}\t{item.Description}\t{item.Name2}\t{item.Description2}");
        }
    }
}


public sealed class Data
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Name2 { get; set; }
    public string Description { get; set; }
    public string Description2 { get; set; }
}

我们的想法是按ID进行分组,然后为每个组创建该组中所有项目的聚合,并在浏览具有该数据的每个对象时填写成员。

答案 1 :(得分:1)

只是扩展@joseph-serido的答案,我会为&#34;转换&#34;创建一个方法。一组Data具有相同的密钥到一个Data实例。

类似的东西:

using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static Data GetDataFromGroup(IGrouping<int, Data> dataGroup)
    {
        Data data = new Data();
        data.ID = dataGroup.Key;
        data.Description = dataGroup.Select(d => d.Description).FirstOrDefault(s => !string.IsNullOrWhiteSpace(s))?? string.Empty;
        data.Description2 = dataGroup.Select(d => d.Description2).FirstOrDefault(s => !string.IsNullOrWhiteSpace(s))?? string.Empty;
        data.Name = dataGroup.Select(d => d.Name).FirstOrDefault(s => !string.IsNullOrWhiteSpace(s))?? string.Empty;
        data.Name2 = dataGroup.Select(d => d.Name2).FirstOrDefault(s => !string.IsNullOrWhiteSpace(s))?? string.Empty;
        return data;
    }

    public static void Main()
    {
        var dataItems = new List<Data>
        {
            new Data { ID = 555, Name = "newname", Description = "a descript" },
            new Data { ID = 555, Name2 = "name2", Description2 = "Description2name" },
            new Data { ID = 543, Name = "onename", Description = "myname" },
        };

        var computedData = dataItems
            .GroupBy(x => x.ID, x => x)
            .Select(g => GetDataFromGroup(g));

        foreach (var item in computedData)
        {
            Console.WriteLine($"{item.ID}\t{item.Name}\t{item.Description}\t{item.Name2}\t{item.Description2}");
        }   
    }
}


public sealed class Data
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Name2 { get; set; }
    public string Description { get; set; }
    public string Description2 { get; set; }
}

there给出与Joseph代码相同的结果

我认为你有两个好处:

  • 更有效率,因为每个属性后它停止了ciclying 第一个非空条目,使用FirstOrDefault代替Aggregate;但实际上,你不会有任何明显的 只要数据的数量不够大就会产生差异。
  • 更灵活:在方法中你可以插入更复杂的逻辑(例如,如果&#34;描述&#34;在多个元素中有一个有效值会发生什么?拿第一个?连接它们?还有什么?)

一般来说,我认为使用Linq设施是好的,只要它使代码更具可读性。 在这种情况下,我认为从一个组到单个项目的翻译值得一个单独的方法