fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. static class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. var list1 = new int?[] {1, 2, 3, 4, 5};
  10. var list2 = new int?[] {3, 4, 5, 6, 7};
  11.  
  12. var joined = list1.FullOuterJoin(list2, a => a, b => b, (a, b, c) => new {list1=a, list2=b});
  13.  
  14. joined.ToList().ForEach(Console.WriteLine);
  15. }
  16. }
  17.  
  18. internal static class MyExtensions
  19. {
  20. private static IDictionary<TK, IEnumerable<TV>> ToDictionary<TK,TV>(this IEnumerable<IGrouping<TK, TV>> grouping)
  21. {
  22. return grouping.ToDictionary(g => g.Key, g => g.AsEnumerable());
  23. }
  24.  
  25. private static IEnumerable<TV> OuterGet<TK, TV>(this IDictionary<TK, IEnumerable<TV>> dict, TK k, TV d=default(TV))
  26. {
  27. IEnumerable<TV> result;
  28. return dict.TryGetValue(k, out result) ? result : new [] { d };
  29. }
  30.  
  31. internal static IList<TR> FullOuterJoin<TA, TB, TK, TR>(this IEnumerable<TA> a,
  32. IEnumerable<TB> b,
  33. Func<TA, TK> selectKeyA, Func<TB, TK> selectKeyB,
  34. Func<TA, TB, TK, TR> projection,
  35. TA defaultA=default(TA), TB defaultB=default(TB))
  36. {
  37. var adict = a.GroupBy(selectKeyA).ToDictionary();
  38. var bdict = b.GroupBy(selectKeyB).ToDictionary();
  39.  
  40. var keys = adict.Keys.Union(bdict.Keys);
  41.  
  42. var join = from key in keys
  43. from xa in adict.OuterGet(key, defaultA)
  44. from xb in bdict.OuterGet(key, defaultB)
  45. select projection(xa, xb, key);
  46.  
  47. return join.ToList();
  48. }
  49. }
  50.  
  51.  
Success #stdin #stdout 0.06s 37288KB
stdin
Standard input is empty
stdout
{ list1 = 1, list2 =  }
{ list1 = 2, list2 =  }
{ list1 = 3, list2 = 3 }
{ list1 = 4, list2 = 4 }
{ list1 = 5, list2 = 5 }
{ list1 = , list2 = 6 }
{ list1 = , list2 = 7 }