Skip to content

Instantly share code, notes, and snippets.

@squeuei
Last active January 8, 2025 14:25
Show Gist options
  • Save squeuei/6fa8ef4ce2783ea7ada4c0a21f0fd394 to your computer and use it in GitHub Desktop.
Save squeuei/6fa8ef4ce2783ea7ada4c0a21f0fd394 to your computer and use it in GitHub Desktop.
How to build a cartesian product from vectors in a single formula with spilled array.

How to build a cartesian product from vectors in a single formula with spilled array.

Suppose that you have a set of row vectors and want to build a cartesian product of them on Microsoft Excel. You can build it with a single formula with spilled array. It may require newer versions of Excel. Columns of each rows don't have to be the same. Of course you can use VSTACK to build an input on the fly, or use spilled range operator like A1# if possible. If your input data contains commas, you can modify the formula by replacing the comma separator in both &","& and TEXTSPLIT(B,",") with any character that won't appear in your data (for example, using a pipe symbol | or semicolon ;).

=LET(
INPUT, A1:M2,
CARTESIAN_PRODUCT, DROP(REDUCE("",REDUCE(TRANSPOSE(CHOOSEROWS(INPUT,1)), SEQUENCE(ROWS(INPUT)-1,,2),LAMBDA(X,Y, TOCOL(X &","&CHOOSEROWS(INPUT,Y)))),LAMBDA(A,B, VSTACK(A,TEXTSPLIT(B,",")))),1),
FILTER(CARTESIAN_PRODUCT,BYROW(CARTESIAN_PRODUCT="",LAMBDA(X,NOT(OR(X)))))
)

Example

This example is taken from here

Input:

1 2 3 4 5 6 7 8 9 10 11 12 13

(Suppose that ♠ is in cell A1)

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13

Ref. (Excel)TEXTSPLIT関数をスピル(複数のテキストに適用)させる - いきなり答える備忘録

スピル配列を使って一つの式でデカルト積を作る

複数の行ベクタからなる集合のデカルト積(直積集合)を構築したいとき、スピル配列のおかげで以下の式を使えば出来る。新しめのExcelが必要かも。入力ベクタの列数は揃っていなくても動作する。もちろん入力はVSTACKを使って構築してもいいし、可能ならスピル範囲演算子を使ってもよい。入力データにカンマが含まれている場合は、 &","&TEXTSPLIT(B,",") の両方のカンマをなんか適当な文字に置き換えて使うことができる。

=LET(
INPUT, A1:M2,
CARTESIAN_PRODUCT, DROP(REDUCE("",REDUCE(TRANSPOSE(CHOOSEROWS(INPUT,1)), SEQUENCE(ROWS(INPUT)-1,,2),LAMBDA(X,Y, TOCOL(X &","&CHOOSEROWS(INPUT,Y)))),LAMBDA(A,B, VSTACK(A,TEXTSPLIT(B,",")))),1),
FILTER(CARTESIAN_PRODUCT,BYROW(CARTESIAN_PRODUCT="",LAMBDA(X,NOT(OR(X)))))
)

直積集合 - Wikipediaの例を用いる。

Input:

1 2 3 4 5 6 7 8 9 10 11 12 13

(♠がA1セルにあるとする)

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13

参考にしたサイト (Excel)TEXTSPLIT関数をスピル(複数のテキストに適用)させる - いきなり答える備忘録

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment