From f21f35cf420cde39692a877198dccf9671ae4343 Mon Sep 17 00:00:00 2001 From: Tau <4602612+bash@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:24:21 +0200 Subject: [PATCH] Update out-of-date Cartesian product docs --- .../cartesian-product.md | 57 +++++++++++++------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/Documentation/src/enumerable-extensions/cartesian-product.md b/Documentation/src/enumerable-extensions/cartesian-product.md index 96b7528f..4d909744 100644 --- a/Documentation/src/enumerable-extensions/cartesian-product.md +++ b/Documentation/src/enumerable-extensions/cartesian-product.md @@ -1,38 +1,61 @@ ## CartesianProduct -In mathematics, specifically set theory, the Cartesian product of two sets A and B, denoted AƗB, is the set of all ordered pairs (a, b) where a is in A and b is in B. +In mathematics, specifically set theory, the Cartesian product of two sets A and B, denoted AƗB, +is the set of all ordered pairs (a, b) where a āˆˆ A and b āˆˆ B. -The CartesianProduct extension function returns all possible pairs of two given IEnumerables. - -There are two overloads, one which lets you choose +In other words: The Cartesian product produces all possible pairs of two given `IEnumerable`s. ![cartesian-product with marbles](cartesian-product.svg "Marble me!") +### Recipe +The Cartesian product can be easily implemented ad-hoc using LINQ's built-in `SelectMany` extension function: + +```cs +using System; +using System.Linq; + +// Version A: Get each pair as a tuple +var result = sequenceA.SelectMany(_ => sequenceB, ValueTuple.Create); + +// Version B: Transform each pair using a selector +var result = sequenceA.SelectMany(_ => sequenceB, (a, b) => ...); + +// Version C: Using LINQs declarative query syntax +var result = + from a in sequenceA + from b in sequenceB + select ...; +``` + + ### Examples Two sequences as input: -``` +``` smiles = [šŸ˜€, šŸ˜, šŸ™„] fruits = [šŸ‰, šŸŒ, šŸ‡, šŸ“] -``` +``` -The cartesian products of smiles and fruits: +The Cartesian products of smiles and fruits: -``` -smiles Ɨ fruits => [[šŸ˜€, šŸ‰], [šŸ˜€, šŸŒ], [šŸ˜€, šŸ‡], [šŸ˜€, šŸ“], - [šŸ˜, šŸ‰], [šŸ˜, šŸŒ], [šŸ˜, šŸ‡], [šŸ˜, šŸ“], +``` +smiles Ɨ fruits => [[šŸ˜€, šŸ‰], [šŸ˜€, šŸŒ], [šŸ˜€, šŸ‡], [šŸ˜€, šŸ“], + [šŸ˜, šŸ‰], [šŸ˜, šŸŒ], [šŸ˜, šŸ‡], [šŸ˜, šŸ“], [šŸ™„, šŸ‰], [šŸ™„, šŸŒ], [šŸ™„, šŸ‡], [šŸ™„, šŸ“]] ``` -In this C# example you see how all Playing cards are in fact a cartesian product of a suit and a value. +In this C# example you see how all playing cards are in fact a Cartesian products of a suit and a value. -This example uses the overload with our own selector, because we just want a sequence of strings. +This example uses the overload with a selector, because we just want a sequence of strings. ```cs -var suits = ImmutableList.Create("ā™ ", "ā™£", "ā™„", "ā™¦"); -var values = - ImmutableList.Create("2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"); +using System; +using System.Linq; +using Funcky; + +var suits = Sequence.Return("ā™ ", "ā™£", "ā™„", "ā™¦"); +var values = Sequence.Return("2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"); -var allCards = suits.CartesianProduct(values, (suit, value) => $"{value}{suit}"); -``` +var deck = suits.SelectMany(_ => values, (suit, value) => $"{value}{suit}"); +```