Blishton
Blishton

Reputation: 109

LINQ Join List of List

Using LINQ, how can I join (Inner Join) list of list datas

Example datas:

List<List<string>> datas1 = new List<List<string>>();
datas1.add(new List() { "1", "Item 1" });
datas1.add(new List() { "2", "Item 2" });
datas1.add(new List() { "3", "Item 3" });

List<List<string>> datas2 = new List<List<string>>();
datas1.add(new List() { "1", "20" });
datas1.add(new List() { "2", "10" });

Expected Result in List<List<string>>:

List("1", "Item 1", "20");
List("2", "Item 2", "10");

I try

var result = datas1
      .Join(datas2, d1 => datas1[0], d2 => datas2[0], (d1, d2) => { d1 })
      .ToList();

I get Empty result, then try :

var result = datas1
          .Join(datas2, d1 => datas1[0][0], d2 => datas2[0][0], (d1, d2) => { d1 })
          .ToList();

I get duplicate result for each datas1.

Upvotes: 3

Views: 7017

Answers (2)

Kaf
Kaf

Reputation: 33809

//Sample data
List<List<string>> datas1 = new List<List<string>>();
datas1.Add(new List<string>() { "1", "Item 1" });
datas1.Add(new List<string>() { "2", "Item 2" });
datas1.Add(new List<string>() { "3", "Item 3" });

List<List<string>> datas2 = new List<List<string>>();
datas2.Add(new List<string>() { "1", "20" });
datas2.Add(new List<string>() { "2", "10" });

You need to join datas1 and datas2 on d1[0][0] equals d2[0][0] as follows:

//Query
var result = (from d1 in datas1
              join d2 in datas2 on d1[0][0] equals d2[0][0]
              select new List<string> { d1[0], d1[1], d2[1] })
             .ToList();

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500375

You're not using the parameters within your lambda expressions in the joins - you've used datas1[0] and datas2[0] instead of d1[0] and d2[0]. Additionally, your projection to the result doesn't give you want you've said you want.

Your query should be like this:

var result = datas1
      .Join(datas2, d1 => d1[0], d2 => d2[0], 
            (d1, d2) => new List<string> { d1[0], d1[1], d2[1] })
      .ToList();

Or you could use a query expression:

var result = (from d1 in datas1
              join d2 in datas2 on d1[0] equals d2[0]
              select new List<string> { d1[0], d1[1], d2[1] })
             .ToList();

(Personally I'd stick with the non query expression version in this case, I think.)

However, it would be better not to have a List<List<string>> though, but to use appropriate types for all your data - possibly with an anonymous type for the result. For example, you might then have something like:

var result = datas1
      .Join(datas2, d1 => d1.Id, d2 => d2.Id, 
            (d1, d2) => new { d1.Id, d1.Name, d2.Description })
      .ToList();

You'd also then be able to store numbers in int values rather than in strings...

Upvotes: 3

Related Questions