F#、C#、SQLで直積
Seq.collectやSelectManyが理解しづらいので簡単なコードで整理してみました。
F#
[<Test>]
let ``cartesian product`` () =
let numbers = seq {for i in 1 .. 3 -> i}
let results =
numbers
|> Seq.collect (fun n1 -> numbers |> Seq.map (fun n2 -> n1, n2))
results
|> Seq.iter (printfn "%A")
C#
[TestMethod]
public void TestCartesianProduct()
{
var numbers = Enumerable.Range(1, 3);
var results = numbers
.SelectMany(n1 => numbers.Select(n2 => Tuple.Create(n1, n2)));
results
.ToList()
.ForEach(Console.WriteLine);
}
C# (LINQ)
[TestMethod]
public void TestCartesianProduct_Linq()
{
var numbers = Enumerable.Range(1, 3);
var results =
from n1 in numbers
from n2 in numbers
select Tuple.Create(n1, n2);
results
.ToList()
.ForEach(Console.WriteLine);
}
SQL
SQL Server 2008を使っています。再帰クエリでつくった連番をテーブル型の変数に格納し、それから結合しています。
declare @numbers table (n int);with x (id) as (
select 1
union all
select id + 1 from x where id + 1 <= 3
)insert into @numbers select * from x;
select a.n n1, b.n n2 from @numbers a, @numbers b
出力結果
出力結果はいずれも1,2,3の集合の直積になります。
n1 | n2 |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
2 | 2 |
2 | 3 |
3 | 1 |
3 | 2 |
3 | 3 |