So generieren Sie in PHP alle Kombinationen von Elementen in mehreren Arrays

Lesezeit: 8 Minuten

Ich versuche, alle Kombinationen von Elementen in mehreren Arrays zu finden. Die Anzahl der Arrays ist zufällig (dies kann 2, 3, 4, 5 … sein). Die Anzahl der Elemente in jedem Array ist auch zufällig …

Zum Beispiel habe ich die 3 Arrays:

$arrayA = array('A1','A2','A3');
$arrayB = array('B1','B2','B3');
$arrayC = array('C1','C2');

Ich möchte ein Array mit 3 x 3 x 2 = 18 Kombinationen generieren:

  • A1, B1, C1
  • A1, B1, C2
  • A1, B2, C1
  • A1, B2, C2
  • A1, B3, C1
  • A1, B3, C2
  • A2, B1, C1
  • A2, B1, C2 …

Das Problem besteht darin, eine Funktion mit einer variablen Anzahl von Quellarrays zu erstellen …

  • Sie möchten immer ein Element von jede einzelne Reihe?

    – Ziege

    19. Dezember 2011 um 20:30 Uhr

So generieren Sie in PHP alle Kombinationen von Elementen in
Krzysztof

Hier ist rekursive Lösung:

function combinations($arrays, $i = 0) {
    if (!isset($arrays[$i])) {
        return array();
    }
    if ($i == count($arrays) - 1) {
        return $arrays[$i];
    }

    // get combinations from subsequent arrays
    $tmp = combinations($arrays, $i + 1);

    $result = array();

    // concat each array from tmp with each element from $arrays[$i]
    foreach ($arrays[$i] as $v) {
        foreach ($tmp as $t) {
            $result[] = is_array($t) ? 
                array_merge(array($v), $t) :
                array($v, $t);
        }
    }

    return $result;
}

print_r(
    combinations(
        array(
            array('A1','A2','A3'), 
            array('B1','B2','B3'), 
            array('C1','C2')
        )
    )
);

  • Wie soll ich diese Funktion ändern, wenn ich die eindeutigen Kombinationen für duplizierte Arrays möchte? Zum Beispiel, wenn ich array(‘A1′,’A2′,’A3’), array(‘A1′,’A2′,’A3’), array(‘C1′,’C2’) habe und ich möchte als Ergebnis “A1, A2, C1”, “A1, A3, C1” usw., aber NEIN “A1, A1, C1” ? Außerdem (wenn ich nicht zu viel verlange 😉 {“A1”, “A2”, “C1”} ist es dasselbe wie {“A2”, “A1”, “C1”}, also möchte ich nur 1 Kombination?

    – Alex Angelico

    30. Mai 2013 um 1:23 Uhr

  • @AlexAngelico – und für alle anderen mit derselben Frage siehe array_unique, php.net/manual/en/function.array-unique.php

    – Daniel Bros

    4. April 2017 um 3:25 Uhr


  • hat mein A gerettet[…]

    – Amin Eshtiaghi

    18. August 2020 um 14:38 Uhr

So generieren Sie in PHP alle Kombinationen von Elementen in
Barfon

Dies ist ein kartesisches Produkt, und ich habe vor nicht allzu langer Zeit dieselbe Frage gestellt. Hier ist das Algorithmus, der auf der PHP-Website veröffentlicht wird.

function array_cartesian_product($arrays)
{
    $result = array();
    $arrays = array_values($arrays);
    $sizeIn = sizeof($arrays);
    $size = $sizeIn > 0 ? 1 : 0;
    foreach ($arrays as $array)
        $size = $size * sizeof($array);
    for ($i = 0; $i < $size; $i ++)
    {
        $result[$i] = array();
        for ($j = 0; $j < $sizeIn; $j ++)
            array_push($result[$i], current($arrays[$j]));
        for ($j = ($sizeIn -1); $j >= 0; $j --)
        {
            if (next($arrays[$j]))
                break;
            elseif (isset ($arrays[$j]))
                reset($arrays[$j]);
        }
    }
    return $result;
}

  • Der Link auf die PHP-Website sagt offenbar nichts über diese Funktion aus. Können Sie ein Beispiel für den Aufruf geben?

    – JohannesK

    9. Juli 2014 um 0:28 Uhr


  • Diese Funktion benötigt mehr als 2,5-mal so lange wie die Funktion von Lolo, um dasselbe Array zu verarbeiten.

    – Richard – Rogue Wave Limited

    11. September 2014 um 16:26 Uhr

1646860446 41 So generieren Sie in PHP alle Kombinationen von Elementen in
Gilhermo Luna

Dieser Code erhält neben der Einfachheit alle Kombinationen mehrerer Arrays und bewahrt Schlüssel.

function get_combinations($arrays) {
    $result = array(array());
    foreach ($arrays as $property => $property_values) {
        $tmp = array();
        foreach ($result as $result_item) {
            foreach ($property_values as $property_key => $property_value) {
                $tmp[] = $result_item + array($property_key => $property_value);
            }
        }
        $result = $tmp;
    }
    return $result;
}

Beispiel:

Array
(
    Array
    (
        '1' => 'White',
        '2' => 'Green',
        '3' => 'Blue'
    ),
    Array
    (
        '4' =>' Small',
        '5' => 'Big'
    )
)

Wird zurückkehren:

Array
(
    [0] => Array
    (
        [1] => White
        [4] =>  Small
    )
    [1] => Array
    (
        [1] => White
        [5] => Big
    )
    [2] => Array
    (
        [2] => Green
        [4] =>  Small
    )
    [3] => Array
    (
        [2] => Green
        [5] => Big
    )
    [4] => Array
    (
        [3] => Blue
        [4] =>  Small
    )
    [5] => Array
    (
        [3] => Blue
        [5] => Big
    )
)

  • Keine Ahnung, warum jemand anderes dies abgelehnt hat. Diese Lösung funktionierte perfekt für mich und bewahrte Array-Schlüssel so, wie ich es wollte. +1

    – Eric Seestrand

    16. August 2016 um 18:46 Uhr

  • Diese Lösung funktionierte perfekt für mich, musste ein wenig optimieren, um mehrere assoziative Arrays zu kombinieren.

    – mk1024

    7. November 2018 um 18:01 Uhr

Ich mag diese Lösung: https://stackoverflow.com/a/33259643/3163536, aber um die eigentliche Frage zu beantworten (die davon ausgeht, dass Die Anzahl der Elemente jeder Kombination sollte gleich der Anzahl der eingehenden Arrays sein) sollte die Funktion geändert werden:

function getCombinations(...$arrays)
    {
        $result = [[]];
        foreach ($arrays as $property => $property_values) {
            $tmp = [];
            foreach ($result as $result_item) {
                foreach ($property_values as $property_value) {
                    $tmp[] = array_merge($result_item, [$property => $property_value]);
                }
            }
            $result = $tmp;
        }
        return $result;
    }

Die Verwendung:

$arrayA = array('A1','A2','A3');
$arrayB = array('B1','B2','B3');
$arrayC = array('C1','C2');

print_r(getCombinations($arrayA, $arrayB, $arrayC));

Das Ergebnis:

Array
(
    [0] => Array
        (
            [0] => A1
            [1] => B1
            [2] => C1
        )

    [1] => Array
        (
            [0] => A1
            [1] => B1
            [2] => C2
        )

    [2] => Array
        (
            [0] => A1
            [1] => B2
            [2] => C1
        )

    [3] => Array
        (
            [0] => A1
            [1] => B2
            [2] => C2
        )

    [4] => Array
        (
            [0] => A1
            [1] => B3
            [2] => C1
        )

    [5] => Array
        (
            [0] => A1
            [1] => B3
            [2] => C2
        )

    [6] => Array
        (
            [0] => A2
            [1] => B1
            [2] => C1
        )

    [7] => Array
        (
            [0] => A2
            [1] => B1
            [2] => C2
        )

    [8] => Array
        (
            [0] => A2
            [1] => B2
            [2] => C1
        )

    [9] => Array
        (
            [0] => A2
            [1] => B2
            [2] => C2
        )

    [10] => Array
        (
            [0] => A2
            [1] => B3
            [2] => C1
        )

    [11] => Array
        (
            [0] => A2
            [1] => B3
            [2] => C2
        )

    [12] => Array
        (
            [0] => A3
            [1] => B1
            [2] => C1
        )

    [13] => Array
        (
            [0] => A3
            [1] => B1
            [2] => C2
        )

    [14] => Array
        (
            [0] => A3
            [1] => B2
            [2] => C1
        )

    [15] => Array
        (
            [0] => A3
            [1] => B2
            [2] => C2
        )

    [16] => Array
        (
            [0] => A3
            [1] => B3
            [2] => C1
        )

    [17] => Array
        (
            [0] => A3
            [1] => B3
            [2] => C2
        )

)

Ich weiß, dass diese Frage alt ist, aber ich habe heute das gleiche Problem und beschlossen, den neuen Generator auszuprobieren:

function generateCombinations(array $array) {
    foreach (array_pop($array) as $value) {
        if (count($array)) {
            foreach (generateCombinations($array) as $combination) {
                yield array_merge([$value], $combination);
            };
        } else {
            yield [$value];
        }
    }
}

foreach (generateCombinations(['a' => ['A'], 'b' => ['B'], 'c' => ['C', 'D'], 'd' => ['E', 'F', 'G']]) as $c) {
        var_dump($c);
    }

Ergebnis:

array(4) {
[0]=>
string(1) "E"
[1]=>
string(1) "C"
[2]=>
string(1) "B"
[3]=>
string(1) "A"
}
array(4) {
[0]=>
string(1) "E"
[1]=>
string(1) "D"
[2]=>
string(1) "B"
[3]=>
string(1) "A"
}
array(4) {
[0]=>
string(1) "F"
[1]=>
string(1) "C"
[2]=>
string(1) "B"
[3]=>
string(1) "A"
}
array(4) {
[0]=>
string(1) "F"
[1]=>
string(1) "D"
[2]=>
string(1) "B"
[3]=>
string(1) "A"
}
array(4) {
[0]=>
string(1) "G"
[1]=>
string(1) "C"
[2]=>
string(1) "B"
[3]=>
string(1) "A"
}
array(4) {
[0]=>
string(1) "G"
[1]=>
string(1) "D"
[2]=>
string(1) "B"
[3]=>
string(1) "A"
}

  • Wenn die Reihenfolge keine Rolle spielt, handelt es sich um eine Kombination. Wenn die Reihenfolge wichtig ist, handelt es sich um eine Permutation. In diesem Fall handelt es sich um eine Permutation und nicht um eine Kombination.

    – Pol Dellaiera

    20. Dezember 2016 um 21:01 Uhr


  • das ist die einfachste lösung

    – Clark

    27. März 2018 um 21:04 Uhr

  • Gibt es eine Möglichkeit, dies zu erreichen? array(4) { 'd' => string(1) "E" 'c' => string(1) "C" 'b' => string(1) "B" 'a' => string(1) "A" }

    – Gläser

    29. März 2018 um 14:36 ​​Uhr


  • Problemumgehung für meine Frage: Erstellen Sie ein solches Array ['a' => [['key' => 'a', 'value' => 'A'], ['key' => 'a', 'value' => 'n']]]

    – Gläser

    29. März 2018 um 14:45 Uhr

  • Nur für den Fall, dass jemand möchte, dass die Elemente des ersten Arrays bei der ersten Verwendung erscheinen array_shift anstatt array_pop bei Zeile 2.

    – qwertynik

    23. Februar um 5:48 Uhr

1646860446 342 So generieren Sie in PHP alle Kombinationen von Elementen in
Eugen Fedorenko

Noch eine Idee:

$ar = [
    'a' => [1,2,3],
    'b' => [4,5,6],
    'c' => [7,8,9]
];

$counts = array_map("count", $ar);
$total = array_product($counts);
$res = [];

$combinations = [];
$curCombs = $total;

foreach ($ar as $field => $vals) {
    $curCombs = $curCombs / $counts[$field];
    $combinations[$field] = $curCombs;
}

for ($i = 0; $i < $total; $i++) {
    foreach ($ar as $field => $vals) {
        $res[$i][$field] = $vals[($i / $combinations[$field]) % $counts[$field]];
    }
}

var_dump($res);

  • Wenn die Reihenfolge keine Rolle spielt, handelt es sich um eine Kombination. Wenn die Reihenfolge wichtig ist, handelt es sich um eine Permutation. In diesem Fall handelt es sich um eine Permutation und nicht um eine Kombination.

    – Pol Dellaiera

    20. Dezember 2016 um 21:01 Uhr


  • das ist die einfachste lösung

    – Clark

    27. März 2018 um 21:04 Uhr

  • Gibt es eine Möglichkeit, dies zu erreichen? array(4) { 'd' => string(1) "E" 'c' => string(1) "C" 'b' => string(1) "B" 'a' => string(1) "A" }

    – Gläser

    29. März 2018 um 14:36 ​​Uhr


  • Problemumgehung für meine Frage: Erstellen Sie ein solches Array ['a' => [['key' => 'a', 'value' => 'A'], ['key' => 'a', 'value' => 'n']]]

    – Gläser

    29. März 2018 um 14:45 Uhr

  • Nur für den Fall, dass jemand möchte, dass die Elemente des ersten Arrays bei der ersten Verwendung erscheinen array_shift anstatt array_pop bei Zeile 2.

    – qwertynik

    23. Februar um 5:48 Uhr

1646860447 651 So generieren Sie in PHP alle Kombinationen von Elementen in
F.Müller

Hier ist ein Code, der einzigartige Kombinationen aus einer Reihe von Zahlen generiert.

Wenn Sie eine Liste mit Zahlen haben, z 1,3,4,7,12 Sie können Sätze von generieren X Nummern, alle einzigartig, keine sich wiederholenden.

Die erste Funktion arbeitet in PHP 7.4 oder höher, und der zweite verwendet Schlüssel zum Speichern der Werte. Beide funktionieren laut Benchmark sehr gut.

function get_combos74($map, $size, &$generated = [], $loop = 1, $i = 0, $prefix = [])
{
    if ($loop == 1) {
        sort($map);
    }

    for (; $i < count($map); $i++) {
        if ($loop < $size) {
            get_combos74($map, $size, $generated, $loop + 1, $i + 1, [...$prefix, $map[$i]]);
        } else {
            $generated[] = [...$prefix, $map[$i]];
        }
    }

    return $generated;
}

function get_combosSTR($map, $size, &$generated = [], $loop = 1, $i = 0, $prefix = '')
{
    if ($loop == 1) {
        sort($map);
    }

    for (; $i < count($map); $i++) {
        if ($loop < $size) {
            get_combosSTR($map, $size, $generated, $loop + 1, $i + 1, "$prefix{$map[$i]}:");
        } else {
            $generated["$prefix{$map[$i]}"] = 0;
        }
    }

    return $generated;
}

984450cookie-checkSo generieren Sie in PHP alle Kombinationen von Elementen in mehreren Arrays

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy