Joining 2 lists with condition

2.4k Views Asked by At

I want to join 2 lists. Students and Persons. Both Student and Person has id and a name variable, plus Student has another variable called isStudying. I want to join all Students to Person with the isStudying variable.

enter image description here

var persons = new Person { id = 1, name = "John" };
var persons = new Person { id = 2, name = "Ace" };
var persons = new Person { id = 3, name = "Mike" };
var persons = new Person { id = 4, name = "Yob" };
var persons = new Person { id = 5, name = "Ken" };

var students = new Student { id = 2, name = "Ace", isStudying=true };
var students = new Student { id = 3, name = "Mike", isStudying = true };
var students = new Student { id = 5, name = "Ken", isStudying = true };

persons.Addrange(students.where(student.id.contain(persons.id)));
3

There are 3 best solutions below

0
On

Try This:

 public class Person
    {
        public int id { get; set; }
        public string name { get; set; }
    }

    public class Student
    {
        public int id { get; set; }
        public string name { get; set; }
        public bool isStudying { get; set; }
    }

    var persons = new List<Person> { new Person { id = 1, name = "John" },
         new Person { id = 2, name = "Ace" },
         new Person { id = 3, name = "Mike"},
         new Person { id = 4, name = "Yob" },
         new Person { id = 5, name = "Ken" } };

        var students = new List<Student> { new Student { id = 2, name = "Ace", isStudying = true },
        new Student { id = 3, name = "Mike", isStudying = true },
        new Student { id = 5, name = "Ken", isStudying = true } };

        var allPersons = (from p in persons
                          join s in students on new { first = p.id } equals new { first = s.id } into sjoin
                          from slj in sjoin.DefaultIfEmpty()
                          select new
                          {
                              id = p.id,
                              name = p.name,
                              isStudying = (slj != null ? (slj.isStudying ? "TRUE" : "FALSE") : string.Empty)
                          }).ToList();
0
On

Here is full solution implemented in linq, used inheritance

class Person
{
    public int id { get; set; }
    public string name { get; set; }
}

class Student : Person
{
    public bool isStudying { get; set; }
}

void Main()
{
    var person1 = new Person { id = 1, name = "John" };
    var person2 = new Person { id = 2, name = "Ace" };
    var person3 = new Person { id = 3, name = "Mike" };
    var person4 = new Person { id = 4, name = "Yob" };
    var person5 = new Person { id = 5, name = "Ken" };

    var persons = new List<Person> { person1, person2, person3, person4, person5 };

    var student1 = new Student { id = 2, name = "Ace", isStudying = true };
    var student2 = new Student { id = 3, name = "Mike", isStudying = true };
    var student3 = new Student { id = 5, name = "Ken", isStudying = true };

    var students = new List<Student> { student1, student2, student3 };

    var personsRes = persons.Where(y => students.Select(x => x.id).Contains(y.id));

    Console.WriteLine(personsRes);
}
0
On

For future readers' reference, one simple answer which I provided in comments using LINQ is:

With anonymous types:

persons.Select(p => new { p.id, p.name, students.Any(s => s.id == p.id && s.isStudying) });

Using a custom class (the Student class can actually be re-used):

persons.Select(p => new Student { id = p.id, name = p.name, isStudying = students.Any(s => s.id == p.id && s.isStudying) });