2

I am currently developing an application that requires this senario.

Assuming I have this object

public class ObjectItem
{
   public int Id {get;set;}
   public int Name {get;set;}
   public int Sex {get;set;}
   public int Age {get;set;}
   public string Complexion {get;set;}
}

If we now have two lists of this object

var studentWithAge = new List<ObjectItem>
                  {
                    new ObjectItem {Id = 1, Name = "John", Age = 2},
                    new ObjectItem {Id = 2, Name = "Smith", Age = 5},
                    new ObjectItem {Id = 3, Name = "Juliet", Age = 7},
                  };

var studentWithSexAndComplexion = new List<ObjectItem>
                       {
                          new ObjectItem {Id = 1, Name = "John", Sex = "Male", Complexion = "fair"},
                          new ObjectItem {Id = 2, Name = "Smith", Sex = "Male", Complexion = " "},
                          new ObjectItem {Id = 3, Name = "Juliet", Sex = "Female", Complexion = "Blonde"},
                          new ObjectItem {Id = 4, Name = "Shittu", Sex = "Male", Complexion = "fair"},
                       };

I want to merge these two lists into just one. The end result should look like this.

var CompleteStudentData=new List<ObjectItem>
{
   new ObjectItem{Id=1,Name="John",Sex="Male", Complexion="fair",Age=2},
   new ObjectItem{Id=2,Name="Smith",Sex="Male", Complexion=" ", Age=5},
   new ObjectItem{Id=3,Name="Juliet",Sex="Female", Complexion="Blonde", Age=7},
   new ObjectItem{Id=4,Name="Shittu",Sex="Male", Complexion="fair", Age=0},
}

How do i achieve this? Using Union to merge the two list does not produce the desired result. I would appreciate your help.

Shittu Joseph Olugbenga
  • 6,148
  • 3
  • 24
  • 36

3 Answers3

4
var result = StudentWithAge.Join(StudentWithSexAndComplexion, 
                                 sa => sa.Id,
                                 ssc => ssc.Id,
                                 (sa, ssc) => new ObjectItem
                                 {
                                    Id = sa.Id,
                                    Name = sa.Name, 
                                    Age = sa.Age, 
                                    Sex = ssc.Sex, 
                                    Complexion = ssc.Complexion
                                 }).ToList();

Or, avoiding creation of new objects:

var result = StudentWithAge.Join(StudentWithSexAndComplexion, 
                                 sa => sa.Id,
                                 ssc => ssc.Id,
                                 (sa, ssc) => 
                                 { 
                                    sa.Sex = ssc.Sex; 
                                    sa.Complexion = ssc.Complexion; 
                                    return sa;
                                 }).ToList();

And if you want to add students presented only in the second list, than also:

result.AddRange(StudentWithSexAndComplexion.Where(ssc => !StudentWithAge.Any(sa => sa.Id == ssc.Id)));
aush
  • 2,050
  • 1
  • 12
  • 21
  • Due to the nature of the ObjectItem and the contents of the two lists, could be better to join by Name and not Id. – Rubidium 37 Feb 28 '15 at 17:01
1

Since it's possible that your collections will not have a 1-to-1 correspondence, you would have to do a full outer join. See here for how you can compose it that way.

Here's one way you can get similar results.

Collect all the keys (the ids) from both collections, then perform a left join with each of the collections, then combine the results.

var ids = studentWithAge.Select(s => s.Id)
    .Union(studentWithSexAndComplexion.Select(s => s.Id));
var query =
    from id in ids
    from sa in studentWithAge
                    .Where(sa => sa.Id == id)
                    .DefaultIfEmpty(new ObjectItem { Id = id })
    from ssc in studentWithSexAndComplexion
                    .Where(ssc => ssc.Id == id)
                    .DefaultIfEmpty(new ObjectItem { Id = id })
    select new ObjectItem
    {
        Id = id,
        Name = sa.Name ?? ssc.Name,
        Sex = ssc.Sex,
        Age = sa.Age,
        Complexion = ssc.Complexion,
    };
Community
  • 1
  • 1
Jeff Mercado
  • 113,921
  • 25
  • 227
  • 248
-1

.Net has a function which is concatenating collections:

var concatenatedCollection = StudentWithAge.Concat(StudentWithSexAndComplexion).ToList();

        var StudentWithAge = new List<ObjectItem>()
        {
            new ObjectItem{Id=1,Name="John",Age=2},
            new ObjectItem{Id=2,Name="Smith",Age=5},
            new ObjectItem{Id=3,Name="Juliet",Age=7},   
        };

        var StudentWithSexAndComplexion = new List<ObjectItem>()
        {
            new ObjectItem{Id=1,Name="John",Sex="Male", Complexion="fair"},
            new ObjectItem{Id=2,Name="Smith",Sex="Male", Complexion=" "},
            new ObjectItem{Id=3,Name="Juliet",Sex="Female", Complexion="Blonde"},
            new ObjectItem{Id=4,Name="Shittu",Sex="Male", Complexion="fair"},
        };
        var concatenatedCollection = StudentWithAge.Concat(StudentWithSexAndComplexion).ToList();
StepUp
  • 27,357
  • 12
  • 66
  • 120