Я пытаюсь создать массив со всеми вариациями продукта. Может быть неограниченное количество атрибутов и вариаций.

Предоставляемый массив:

["Shirt"]           # Product
    ["Color"]       # Attribute
        ["Green"]   # Variation
        ["Red"]
        ["Blue"]
    ["Size"]
        ["Small"]
        ["Medium"]
        ["Large"]

Ожидаемый результат:

[0]
    ["type" => "Shirt"]
    ["color" => "Green"]
    ["Size" => "Small"]
[1]
    ["type" => "Shirt"]
    ["color" => "Green"]
    ["Size" => "Medium"]
...
[4]
    ["type" => "Shirt"]
    ["color" => "Red"]
    ["Size" => "Medium"]
[4]
    ["type" => "Shirt"]
    ["color" => "Red"]
    ["Size" => "Large"]

Я пробовал встроенные функции Laravel и PHP, но не добился успеха. Я был бы очень признателен за любое понимание.

0
Brandon Kiefer 25 Сен 2018 в 18:07

2 ответа

Лучший ответ

Используйте три вложенных foreach и отправьте в массив $result на последнем уровне. (Здесь я использовал функцию compact, чтобы сократить код. )

$provided = [
    'Shirt' => [
        'color' => ['green', 'red'],
        'size' => ['Small', 'Medium'],
    ],
]; // Reduced the provided data to reduce the output for sample purposes.

$result = [];

foreach ($provided as $type => $attributes) {
    foreach ($attributes['color'] as $color) {
        foreach ($attributes['size'] as $size) {
            $result[] = compact('type','color','size');
        }
    }
}

var_dump($result);

Будет выходной

array(4) {
  [0]=>
  array(3) {
    ["type"]=>
    string(5) "Shirt"
    ["color"]=>
    string(5) "green"
    ["size"]=>
    string(5) "Small"
  }
  [1]=>
  array(3) {
    ["type"]=>
    string(5) "Shirt"
    ["color"]=>
    string(5) "green"
    ["size"]=>
    string(6) "Medium"
  }
  [2]=>
  array(3) {
    ["type"]=>
    string(5) "Shirt"
    ["color"]=>
    string(3) "red"
    ["size"]=>
    string(5) "Small"
  }
  [3]=>
  array(3) {
    ["type"]=>
    string(5) "Shirt"
    ["color"]=>
    string(3) "red"
    ["size"]=>
    string(6) "Medium"
  }
}
1
Elias Soares 25 Сен 2018 в 15:19

Ваш вопрос, кажется, близок к этому универсальному подходу, который у меня есть:

$arr = [
    'size'  => [ 'XS', 'S', 'M' ],
    'color' => [ 'yellow', 'brown', 'white' ],
    'weight'=> [
        'light' => [
                'super',
                'medium'
         ],
        'normal',
        'heavy' => [
            'regular',
            'most', 
            'overload'
        ]
    ]
];


function variations( $array ){

    if( empty( $array ) ) return [];

    function traverse( $array, $parent_ind ){
        $r = [];
        $pr = '';
        if( !is_numeric($parent_ind) )
            $pr = $parent_ind . '-';
        foreach( $array as $ind=>$el ) {
            if ( is_array( $el ) ) {
                $r = array_merge( $r, traverse( $el, $pr . ( is_numeric( $ind ) ? '' : $ind ) ) );
            }else
                if ( is_numeric( $ind ) )
                    $r[] = $pr . $el;
                else
                    $r[] = $pr . $ind . '-' . $el;
        }
        return $r;
    }

    //1. Go through entire array and transform elements that are arrays into elements, collect keys
    $keys = [];$size = 1;
    foreach( $array as $key=>$elems ) {
        if ( is_array( $elems ) ) {
            $rr = [];
            foreach ( $elems as $ind=>$elem ) {
                if ( is_array( $elem ) )
                    $rr = array_merge( $rr, traverse( $elem, $ind ) );
                else $rr[] = $elem;
            }
            $array[ $key ] = $rr;
            $size *= count( $rr );
        }
        $keys[] = $key;
    }

    //2. Go through all new elems and make variations
    $rez = [];
    for( $i = 0; $i < $size; $i++ ) {
        $rez[ $i ] = array();
        foreach( $array as $key => $value ){
            $current = current( $array[ $key ] );
            $rez[ $i ][ $key ] = $current;
        }
        foreach( $keys as $key )
            if( !next( $array[ $key ] ) ) reset( $array[ $key ] );
            else break;
    }

    return $rez;

}


die( print_r( variations( $arr ) ) );

Результат будет массивом всех возможных комбинаций «атрибутов» или чего-то еще (см. ниже). Я использовал его для создания продуктов Test Woocommerce Variable.

Testing started at 11:37 ...
/usr/bin/php /usr/local/bin/phpunit --bootstrap /opt/lampp/htdocs/unittests.lo/wp-content/plugins/test-woocommerce-izettle/tests/bootstrap.php --configuration /opt/lampp/htdocs/unittests.lo/wp-content/plugins/test-woocommerce-izettle/phpunit.xml.dist --teamcity
Array
(
    [0] => Array
        (
            [size] => XS
            [color] => yellow
            [weight] => light-super
        )

    [1] => Array
        (
            [size] => S
            [color] => yellow
            [weight] => light-super
        )

    [2] => Array
        (
            [size] => M
            [color] => yellow
            [weight] => light-super
        )

    [3] => Array
        (
            [size] => XS
            [color] => brown
            [weight] => light-super
        )

    [4] => Array
        (
            [size] => S
            [color] => brown
            [weight] => light-super
        )

    [5] => Array
        (
            [size] => M
            [color] => brown
            [weight] => light-super
        )

    [6] => Array
        (
            [size] => XS
            [color] => white
            [weight] => light-super
        )

    [7] => Array
        (
            [size] => S
            [color] => white
            [weight] => light-super
        )

    [8] => Array
        (
            [size] => M
            [color] => white
            [weight] => light-super
        )

    [9] => Array
        (
            [size] => XS
            [color] => yellow
            [weight] => light-medium
        )

    [10] => Array
        (
            [size] => S
            [color] => yellow
            [weight] => light-medium
        )

    [11] => Array
        (
            [size] => M
            [color] => yellow
            [weight] => light-medium
        )

    [12] => Array
        (
            [size] => XS
            [color] => brown
            [weight] => light-medium
        )

    [13] => Array
        (
            [size] => S
            [color] => brown
            [weight] => light-medium
        )

    [14] => Array
        (
            [size] => M
            [color] => brown
            [weight] => light-medium
        )

    [15] => Array
        (
            [size] => XS
            [color] => white
            [weight] => light-medium
        )

    [16] => Array
        (
            [size] => S
            [color] => white
            [weight] => light-medium
        )

    [17] => Array
        (
            [size] => M
            [color] => white
            [weight] => light-medium
        )

    [18] => Array
        (
            [size] => XS
            [color] => yellow
            [weight] => normal
        )

    [19] => Array
        (
            [size] => S
            [color] => yellow
            [weight] => normal
        )

    [20] => Array
        (
            [size] => M
            [color] => yellow
            [weight] => normal
        )

    [21] => Array
        (
            [size] => XS
            [color] => brown
            [weight] => normal
        )

    [22] => Array
        (
            [size] => S
            [color] => brown
            [weight] => normal
        )

    [23] => Array
        (
            [size] => M
            [color] => brown
            [weight] => normal
        )

    [24] => Array
        (
            [size] => XS
            [color] => white
            [weight] => normal
        )

    [25] => Array
        (
            [size] => S
            [color] => white
            [weight] => normal
        )

    [26] => Array
        (
            [size] => M
            [color] => white
            [weight] => normal
        )

    [27] => Array
        (
            [size] => XS
            [color] => yellow
            [weight] => heavy-regular
        )

    [28] => Array
        (
            [size] => S
            [color] => yellow
            [weight] => heavy-regular
        )

    [29] => Array
        (
            [size] => M
            [color] => yellow
            [weight] => heavy-regular
        )

    [30] => Array
        (
            [size] => XS
            [color] => brown
            [weight] => heavy-regular
        )

    [31] => Array
        (
            [size] => S
            [color] => brown
            [weight] => heavy-regular
        )

    [32] => Array
        (
            [size] => M
            [color] => brown
            [weight] => heavy-regular
        )

    [33] => Array
        (
            [size] => XS
            [color] => white
            [weight] => heavy-regular
        )

    [34] => Array
        (
            [size] => S
            [color] => white
            [weight] => heavy-regular
        )

    [35] => Array
        (
            [size] => M
            [color] => white
            [weight] => heavy-regular
        )

    [36] => Array
        (
            [size] => XS
            [color] => yellow
            [weight] => heavy-most
        )

    [37] => Array
        (
            [size] => S
            [color] => yellow
            [weight] => heavy-most
        )

    [38] => Array
        (
            [size] => M
            [color] => yellow
            [weight] => heavy-most
        )

    [39] => Array
        (
            [size] => XS
            [color] => brown
            [weight] => heavy-most
        )

    [40] => Array
        (
            [size] => S
            [color] => brown
            [weight] => heavy-most
        )

    [41] => Array
        (
            [size] => M
            [color] => brown
            [weight] => heavy-most
        )

    [42] => Array
        (
            [size] => XS
            [color] => white
            [weight] => heavy-most
        )

    [43] => Array
        (
            [size] => S
            [color] => white
            [weight] => heavy-most
        )

    [44] => Array
        (
            [size] => M
            [color] => white
            [weight] => heavy-most
        )

    [45] => Array
        (
            [size] => XS
            [color] => yellow
            [weight] => heavy-overload
        )

    [46] => Array
        (
            [size] => S
            [color] => yellow
            [weight] => heavy-overload
        )

    [47] => Array
        (
            [size] => M
            [color] => yellow
            [weight] => heavy-overload
        )

    [48] => Array
        (
            [size] => XS
            [color] => brown
            [weight] => heavy-overload
        )

    [49] => Array
        (
            [size] => S
            [color] => brown
            [weight] => heavy-overload
        )

    [50] => Array
        (
            [size] => M
            [color] => brown
            [weight] => heavy-overload
        )

    [51] => Array
        (
            [size] => XS
            [color] => white
            [weight] => heavy-overload
        )

    [52] => Array
        (
            [size] => S
            [color] => white
            [weight] => heavy-overload
        )

    [53] => Array
        (
            [size] => M
            [color] => white
            [weight] => heavy-overload
        )

)

Process finished with exit code 0
1
0
Stim 26 Окт 2018 в 08:43