Home > database >  LINQ - Join both lists by last digit
LINQ - Join both lists by last digit

Time:08-25

A sequence of positive integers integerList1 and integerList2 are given. All values in each sequence are different.

Get a set (list of NumberPair values) of all value pairs that satisfy the following conditions:

  • the first element of the pair belongs to the sequence integerList1,
  • the second belongs to integerList2
  • both elements end with the same digit.
  • The NumberPair type includes Value 1, Value 2 fields.
  • The resulting NumberPair list must be sorted in ascending order by the first field, and if they are equal, by the second.

Here is an example:

integerList1: new[] { 1, 12, 4, 5, 78 }
integerList2: new[] { 1, 42, 75, 65, 8, 97 }

Expected result:

expected: new[]
{
     new NumberPair{Item1 = 1, Item2 = 1},
     new NumberPair{Item1 = 5, Item2 = 65},
     new NumberPair{Item1 = 5, Item2 = 75},
     new NumberPair{Item1 = 12, Item2 = 42},
     new NumberPair{Item1 = 78, Item2 = 8}
}

I tried to solve like this

var lastDigitsGroups1 = integerList1.GroupBy(num => num % 10).ToDictionary(kvp => kvp.Key, kvp => kvp.ToList());
var lastDigitsGroups2 = integerList2.GroupBy(num => num % 10).ToDictionary(kvp => kvp.Key, kvp => kvp.ToList());
var intersection = lastDigitsGroups1.Keys.Intersect(lastDigitsGroups2.Keys);
foreach (var item in intersection)
{
    var np = new NumberPair { Item1 = lastDigitsGroups1[item].FirstOrDefault(), Item2 = lastDigitsGroups2[item].FirstOrDefault() };
    yield return np;
}

However, it should be done only using LINQ and even with one LINQ query.

CodePudding user response:

Join both lists by keys as below:

var result = (from a in integerList1
            join b in integerList2 on (a % 10) equals (b % 10)
            select new NumberPair { Item1 = a, Item2 = b }
            )
            .OrderBy(x => x.Item1)
            .ThenBy(x => x.Item2)
            .ToList();

Or

var result = integerList1.Join(integerList2,
                                x => x % 10,
                                y => y % 10,
                                (x, y) => new { x, y })
                        .Select(x => new NumberPair { Item1 = x.x, Item2 = x.y })
                        .OrderBy(x => x.Item1)
                        .ThenBy(x => x.Item2)
                        .ToList();

Demo @ .NET Fiddle

CodePudding user response:

I honestly don't understand your approach, it does not seem to do what you have mentioned in your conditions. If i just take them as requirement, use Enumerable.Zip:

var result = integerList1.Zip(integerList2, (i1, i2) => new NumberPair{Item1 = i1, Item2 = i2} )
    .OrderBy(np => np.Item1)
    .ThenBy(np => np.Item2);
  • Related