Using Linq and C #, how could I merge two lists by some criteria?

Context


public class Item { public int Index; public string Text; } ... var items = new List<Item> { new Item {Index=1, Text="Data #1"}, new Item {Index=8, Text="Data #8"}, new Item {Index=4, Text="Data #4"}, }; 

Code


 var data = (from item in items orderby item.Index select item).ToList(); 

Result


Data [0] = Data No. 1
Data [1] = Data No. 4
Data [2] = Data # 8

What do you need


Data [0] = null
Data [1] = Data No. 1
Data [2] = null
Data [3] = null
Data [4] = Data No. 4
Data [5] = null
Data [6] = null
Data [7] = null
Data [8] = Data # 8

How to achieve this with Linq?

+4
source share
3 answers

Basically, you need a left join between a sequence of numbers and your list of elements:

 var result = (from i in Enumerable.Range(0, items.Max(it => it.Index) + 1) join item in items on i equals item.Index into g from item in g.DefaultIfEmpty() select item).ToList(); 
+4
source

This does what you want:

 var result = Enumerable.Range(0, items.Max(x => x.Index) + 1) .Select(i => items.Where(x => x.Index == i) .Select(x => x.Text) .SingleOrDefault()) .ToList(); 

Result:

  result [0] = null
 result [1] = Data # 1
 result [2] = null
 result [3] = null
 result [4] = Data # 3
 result [5] = null
 result [6] = null
 result [7] = null
 result [8] = Data # 8

You can improve performance by storing the original data in a dictionary:

 Dictionary<int, string> d = items.ToDictionary(x => x.Index, x => x.Text); List<string> result = new List<string>(); for (int i = 0; i < d.Keys.Max() + 1; ++i) { string s; d.TryGetValue(i, out s); result.Add(s); } 
+5
source
 string[] myData = new string[items.Max(item => item.Index)]; foreach(Item myItem in items) { myData[myItem.Index] = myItem.Data; } 
+4
source

All Articles