Home > database >  Join two arrays and get tuple
Join two arrays and get tuple

Time:02-21

let's say I have two collections:

string[] arr1 =
{
    "item-1",
    "item-2",
    "item-3",
    "item-777",
    "item-4"
};

string[] arr2 =
{
    "item-1",
    "item-2",
    "item-3",
    "item-4"
};

TODO: when arr1 element does not match to arr2 element, return: arr1[i] = "empty". return type: IEnumerable<(string, string)>. result should be:

item-1 - item-1
item-2 - item-2
item-3 - item-3
item-777 - empty
item-4 - item-4

My solution doesn't works:

IEnumerable<(string, string)> result = arr1.Join(arr2,
                                      item => item,
                                      item => item ?? "empty",
                                      (item1, item2) => (item1, item2));

foreach (var item in result)
{
  Console.WriteLine($"{item.Item1} - {item.Item2}");
}

Please help.

CodePudding user response:

Sometimes these things are just easier to write with the other syntax

IEnumerable<(string, string)> result =  from a1 in arr1
                                    join a2 in arr2 on a1 equals a2 into j
                                    from a2item in j.DefaultIfEmpty()
                                    select (a1,a2item ?? "empty");

Live example: https://dotnetfiddle.net/tFMNxA


In method syntax it uses GroupJoin and SelectMany

var result =  arr1.GroupJoin(arr2, a1 => a1, a2 => a2, (a1,a2) => (a1,a2))
                  .SelectMany(x => x.a2.DefaultIfEmpty(), (x,y) => (Item1:x.a1, Item2: y?? "empty"));

Live example: https://dotnetfiddle.net/MbBIyQ

CodePudding user response:

With HashSet<T> you can "quickly" find if given item exists in second array. Join method will use HashSet in "background" anyway.

var others = arr2.ToHashSet();
var pairs = arr1.Select(item => (item, others.Contains(item) ? item : "empty"));

foreach (var pair in pairs)
{
    Console.WriteLine($"{pair.First} - {pair.Second}");
}
  • Related