2017 © Pedro Peláez
 

library cartesian-product

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array.

image

bentools/cartesian-product

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array.

  • Monday, March 26, 2018
  • by bpolaszek
  • Repository
  • 3 Watchers
  • 12 Stars
  • 5,717 Installations
  • PHP
  • 6 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 5 Versions
  • 9 % Grown

The README.md

Latest Stable Version License CI Workflow Coverage Total Downloads, (*1)

Cartesian Product

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array., (*2)

Usage

use function BenTools\CartesianProduct\combinations;

$data = [
    'hair' => [
        'blond',
        'black'
    ],
    'eyes' => [
        'blue',
        'green',
        function (array $combination) { // You can use closures to dynamically generate possibilities
            if ('black' === $combination['hair']) { // Then you have access to the current combination being built
                return 'brown';
            }
            return 'grey';
        }
    ]
];

foreach (combinations($data) as $combination) {
    printf('Hair: %s - Eyes: %s' . PHP_EOL, $combination['hair'], $combination['eyes']);
}

Output:, (*3)

Hair: blond - Eyes: blue
Hair: blond - Eyes: green
Hair: blond - Eyes: grey
Hair: black - Eyes: blue
Hair: black - Eyes: green
Hair: black - Eyes: brown

Array output

Instead of using foreach you can dump all possibilities into an array., (*4)

[!WARNING] This will dump all combinations in memory, so be careful with large datasets., (*5)

print_r(combinations($data)->asArray());

Output:, (*6)

Array
(
    [0] => Array
        (
            [hair] => blond
            [eyes] => blue
        )

    [1] => Array
        (
            [hair] => blond
            [eyes] => green
        )

    [2] => Array
        (
            [hair] => blond
            [eyes] => grey
        )

    [3] => Array
        (
            [hair] => black
            [eyes] => blue
        )

    [4] => Array
        (
            [hair] => black
            [eyes] => green
        )

    [5] => Array
        (
            [hair] => black
            [eyes] => brown
        )

)

Combinations count

You can simply count how many combinations your data produce (this will not generate any combination):, (*7)

use function BenTools\CartesianProduct\combinations;

$data = [
    'hair' => [
        'blond',
        'red',
    ],
    'eyes' => [
        'blue',
        'green',
        'brown',
    ],
    'gender' => [
        'male',
        'female',
    ]
];
var_dump(count(combinations($data))); // 2 * 3 * 2 = 12

Filtering combinations

You can filter combinations using the filter method. This is useful if you want to skip some combinations based on certain criteria:, (*8)

use function BenTools\CartesianProduct\combinations;

$data = [
    'hair' => [
        'blond',
        'black'
    ],
    'eyes' => [
        'blue',
        'green',
    ]
];

foreach (combinations($data)->filter(fn (array $combination) => 'green' !== $combination['eyes']) as $combination) {
    printf('Hair: %s - Eyes: %s' . PHP_EOL, $combination['hair'], $combination['eyes']);
}

Map output

You can use the each method to transform each combination into a different format:, (*9)

use App\Entity\Book;

use function BenTools\CartesianProduct\combinations;

$books = [
    'author' => ['Isaac Asimov', 'Arthur C. Clarke'],
    'genre' => ['Science Fiction', 'Fantasy'],
]

foreach (combinations($books)->each(fn (array $combination) => Book::fromArray($combination)) as $book) {
    assert($book instanceof Book);
}

Installation

PHP 8.2+ is required., (*10)

composer require bentools/cartesian-product

Performance test

The following example was executed on my Core i7 personnal computer with 8GB RAM., (*11)

use function BenTools\CartesianProduct\combinations;

$data = array_fill(0, 10, array_fill(0, 5, 'foo'));

$start = microtime(true);
foreach (combinations($data) as $c => $combination) {
    continue;
}
$end = microtime(true);

printf(
    'Generated %d combinations in %ss - Memory usage: %sMB / Peak usage: %sMB',
    ++$c,
    round($end - $start, 3),
    round(memory_get_usage() / 1024 / 1024),
    round(memory_get_peak_usage() / 1024 / 1024)
);

Output:, (*12)

Generated 9765625 combinations in 1.61s - Memory usage: 0MB / Peak usage: 1MB, (*13)

Unit tests

./vendor/bin/pest

Other implementations

th3n3rd/cartesian-product, (*14)

patchranger/cartesian-iterator, (*15)

Benchmark, (*16)

See also

bentools/string-combinations, (*17)

bentools/iterable-functions, (*18)

Credits

Titus on StackOverflow - you really rock., (*19)

The Versions

26/03 2018

dev-master

9999999-dev

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array.

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

23/06 2017

1.2

1.2.0.0

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array.

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

07/06 2017

1.1

1.1.0.0

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array.

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

30/05 2017

1.0.1

1.0.1.0

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array.

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

30/05 2017

1.0

1.0.0.0

A simple, low-memory footprint function to generate all combinations from a multi-dimensionnal array.

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires