1

I have the following model:

class serverMaster
{
    public string vm { get; set; }
    public string bm { get; set; }
    public string incrday { get; set; }
    public string incrtime { get; set; }
    public string fullday { get; set; }
    public string fulltime { get; set; }
    public string backupgroup { get; set; }
    public serverMaster(string vm1, string bm1, string incrday1, string incrtime1, string fullday1, string fulltime1, string backupgroup1)
    {
        vm = vm1;
        bm = bm1;
        incrday = incrday1;
        incrtime = incrtime1;
        fullday = fullday1;
        fulltime = fulltime1;
        backupgroup = backupgroup1;

    }
}

and I have a data set like this:

enter image description here

How can I use Linq to find duplicates in the first column (so for example merge Aether) and concatenate the other fields.

I would ideally like to see output like this:

enter image description here

Josh Hilditch
  • 73
  • 1
  • 6

1 Answers1

1

What you want to do is to GroupBy on the key field (by your comment and model I'm assuming it is vm and then to perform an aggregation operation for the other fields. From your sample data you want to concatenate the strings:

var result = allItems.GroupBy(item => item.vm)
                     .Select(group => new serverMaster {
                         vm = group.Key,
                         incrday = string.Join(", ", group.Select(i => i.incrday)),
                         incrtime = string.Join(", ", group.Select(i => i.incrtime)),
                         fullday = string.Join(", ", group.Select(i => i.fullday)),
                         fulltime = string.Join(", ", group.Select(i => i.fulltime)),
                         backupgroup = string.Join(", ", group.Select(i => i.backupgroup))
                     }).ToList();

As you do not have a default constructor you should:

var result = allItems.GroupBy(item => item.vm)
                     .Select(group => new serverMaster (
                         group.Key,
                         string.Join(", ", group.Select(i => i.incrday)),
                         string.Join(", ", group.Select(i => i.incrtime)),
                         string.Join(", ", group.Select(i => i.fullday)),
                         string.Join(", ", group.Select(i => i.fulltime)),
                         string.Join(", ", group.Select(i => i.backupgroup))
                     )).ToList();

You can have a look at: What's the difference between an object initializer and a constructor?

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • Looks great, but the code here "group => new serverMaster" is asking that I pass parameters. Do I add them? – Josh Hilditch Sep 26 '17 at 06:04
  • 1
    @JoshHilditch - oh true. That is because you do not have a default constructor and instead a constructor that gets all the parameters. I'll update my answer but I recommend to use object initializers instead of the constructor – Gilad Green Sep 26 '17 at 06:06
  • "there is no argument given that corresponds to the required formal parameter 'vm1' os serverMaster. That's what I'm getting. – Josh Hilditch Sep 26 '17 at 06:08
  • Oh ok. Sweet :) – Josh Hilditch Sep 26 '17 at 06:08
  • @JoshHilditch - see update + Have a look at naming conventions in C# for the names of the properties – Gilad Green Sep 26 '17 at 06:09
  • Well that's done it. Thank you, absolute legend. If I could buy you a beer, I would. That was the final piece of my puzzle which is going to save me so many hours of work. Wish I could +100 for this. Thank you. – Josh Hilditch Sep 26 '17 at 06:17
  • 1
    @JoshHilditch - haha :) I wish that sometimes too ;p but the max we can do is mark as solved and upvote :) Glad it helped – Gilad Green Sep 26 '17 at 06:19