You are looking for Cartesian Join. Given jagged array (int[][]
is jagged array, not 2D one)
int[][] Values = new int[][] {
new int[] { 1, 2 },
new int[] { 3, 4 },
};
You can Join
it with itself as
var result = Values
.SelectMany(line => line) // flatten
.Join(Values.SelectMany(line => line), // flatten
x => true,
y => true,
(x, y) => new int[] { x, y });
In case of 2D array int [,]
int[,] Values = new int[,] {
{ 1, 2 },
{ 3, 4 },
};
you can use the same idea, but with OfType
instead of SelectMany
:
var result = Values
.OfType<int>() // flatten
.Join(Values.OfType<int>(), // flatten
x => true,
y => true,
(x, y) => new int[] { x, y });
Let's have a look:
Console.Write(string.Join(Environment.NewLine, result
.Select(line => $"[{string.Join(", ", line)}]")));
Outcome:
[1, 1]
[1, 2]
[1, 3]
[1, 4]
[2, 1]
[2, 2]
[2, 3]
[2, 4]
[3, 1]
[3, 2]
[3, 3]
[3, 4]
[4, 1]
[4, 2]
[4, 3]
[4, 4]
Edit: To get all combinations of 3
items (i.e. {1, 1, 1}, {1, 1, 2} .. {4, 4, 4}
) you can add one more Join
. For jagged array [,]
it can be
var result = Values
.SelectMany(line => line) // flatten
.Join(Values.SelectMany(line => line), // flatten
x => true,
y => true,
(x, y) => (a: x, b: y))
.Join(Values.SelectMany(line => line), // flatten
x => true,
y => true,
(x, y) => new int[] {x.a, x.b, y});
To get all 4 items combinations you can add yet another Join
, etc.:
var result = Values
.SelectMany(line => line) // flatten
.Join(Values.SelectMany(line => line), // flatten
x => true,
y => true,
(x, y) => (a: x, b: y))
.Join(Values.SelectMany(line => line), // flatten
x => true,
y => true,
(x, y) => (a: x.a, b: x.b, c: y))
.Join(Values.SelectMany(line => line), // flatten
x => true,
y => true,
(x, y) => new int[] {x.a, x.b, x.c, y});