Комбинации массива в массив в PHP

#php #arrays

#php #массивы

Вопрос:

Я постараюсь все объяснить 🙂

У меня есть 2 массива:

 $packs = array(
  array(
    'name' => 'Pack 1',
    'zones' => array(
      array('zone' => 2),
      array('zone' => 2),
    )
  ),
  array(
    'name' => 'Pack 2',
    'zones' => array(
      array('zone' => 2),
      array('zone' => 2),
      array('zone' => 2),
    )
  ),
  array(
    'name' => 'Pack 3',
    'zones' => array(
      array('zone' => 2),
      array('zone' => 3),
    )
  ),
  array(
    'name' => 'Pack 4',
    'zones' => array(
      array('zone' => 3),
      array('zone' => 3),
    )
  )
);And products:

$products = array(
    array(
        'id' => '1',
        'zone' => '2'
    ),
    array(
        'id' => '8',
        'zone' => '2'
    ),
    array(
        'id' => '13',
        'zone' => '3'
    ),
    array(
        'id' => '11',
        'zone' => '2'
    ),
    array(
        'id' => '10',
        'zone' => '2'
    ),
    array(
        'id' => '12',
        'zone' => '3'
    )
);
  

Тогда я хотел бы, чтобы все зоны $packs были объединены с этими зонами продуктов.
Например, products_zones являются 2, 2, 3, 2, 2, 3 тогда я хотел бы что-то вроде этого:

Паки:

  • Комбинация 1:
    • Пакет 1 (когда зоны пакетов находятся в зонах продуктов, добавьте пакет в комбинацию и удалите продукты из массива)
    • Пакет 1
  • Комбинация 2:
    • Пакет 1
    • Пакет 3
  • Комбинация 3:
    • Пакет 1
    • Пакет 4
  • Комбинация 4:
    • Пакет 2
    • Пакет 4
  • Комбинация 5:
    • Пакет 2
    • Пакет 2
    • Пакет 4

Я пытаюсь сделать это с помощью рекурсивной функции, но не работает. Я оставляю здесь ссылку с кодом:

 function search_recursive( $packs = array(), $products = array(), $packs_in = array(), $pass = null ) {
    foreach ($packs as $index => $pack) {
        // Get zones to compare
        $arr_zones = array_column($pack['zonas'], 'zona');

        $products_zones = array_column($products, 'zone');

        // Check if pack zones are in product zones
        $cheak_arr = [];
        $arr_zones_temp = $arr_zones;
        foreach ($products_zones as $index2 => $temp_zone) {
            if ( in_array($temp_zone, $arr_zones_temp) ) {
                $cheak_arr[] = $temp_zone;

                foreach ($arr_zones_temp as $key => $value) {
                    if ( $value == $temp_zone ) {
                        unset($arr_zones_temp[$key]);
                        break;
                    }
                }
            }

        }

        if ( count($arr_zones) == count($cheak_arr) ) {
            // I create a index for first time
            $custom_index = ($pass == null) ? $index : $pass;

            // Add pack to array if pack zones are in product zones
            if ( !isset($packs_in[$custom_index]) ) {
                $packs_in[$custom_index] = [
                    'packs' => array($pack)
                ];
            }
            else {
                $packs_in[$custom_index]['packs'][] = $pack;
            }

            // Remove products that have zones same in pack
            $temp_prod = $products;
            foreach ($arr_zones as $zone) {
                foreach ($temp_prod as $key => $value) {
                    if ( $value['zone'] == $zone ) {
                        unset($temp_prod[$key]);
                        break;
                    }
                }
            }

            if ( $pass != null ) {
                $products = $temp_prod;
            }

            if ( !empty($temp_prod) ) {
                // Call myself with less products and index defined
                $packs_in = search_recursive( $packs, $temp_prod, $packs_in, $custom_index );
            }
            else if ( $pass != null ) {
                break;
            }
        }
    }

    return $packs_in;
}
  

Комментарии:

1. Массивы в вашем первом фрагменте недопустимы. Ключи должны быть уникальными, и у вас есть несколько записей с одним и тем же ключом в одном массиве. например array('zone' => 2, 'zone' => 2)

2. Я не понял логики здесь. Почему ожидается комбинация 4, если пакеты 2 и 4 имеют разные зоны?

3. @GrumpyCrouton Да, изменилось! извините

4. @FelippeDuarte, продуктовые зоны 2, 3, 2, 2, 3; Зоны упаковки 2 равны 2, 2, 2, а зоны упаковки 4 равны 3, 3; Если мы объединим зоны Pack2 и зоны Pack3 в ту же комбинацию, что и в продуктовых зонах 2, 2, 2, 3,3

5. Почему pack 1 pack 1 является допустимой комбинацией, поскольку она имеет четыре «2» (2,2,2,2), а продукты имеют только три «2» (2,2,2,3,3)?

Ответ №1:

Я думаю, что я получил то, что вам нужно, но я все еще немного в замешательстве. В любом случае, я предлагаю вам упростить массив «пакетов», как в моем коде ниже:

 <?php

$packs = array(
  array(
    'name' => 'Pack 1',
    'zones' => array(2,2),
  ),
  array(
    'name' => 'Pack 2',
    'zones' => array(2,2,2),
  ),
  array(
    'name' => 'Pack 3',
    'zones' => array(2,3),
  ),
  array(
    'name' => 'Pack 4',
    'zones' => array(3,3),
  )
);

$products = array(
    array(
        'id' => '8',
        'zone' => '2'
    ),
    array(
        'id' => '13',
        'zone' => '3'
    ),
    array(
        'id' => '11',
        'zone' => '2'
    ),
    array(
        'id' => '10',
        'zone' => '2'
    ),
    array(
        'id' => '12',
        'zone' => '3'
    )
);

$product_zones = array_column($products, 'zone');
//let's order an change to a sequence of numbers like 22233
sort($product_zones);
$product_zones = join('', $product_zones);

$combinations = [];

//here we iterate through all packs 1->2,3,4; 2->3,4 3->4 to find if it matches
foreach($packs as $k => $pack) {
    // use k 1 if you can't match the pack with itself
    for ($i = $k, $c = count ($packs); $i < $c; $i  ) {
        //here we do the same as before to combine the packs as string, ex.: 2223
        $pack_zones = array_merge($pack['zones'], $packs[$i]['zones']);
        sort($pack_zones);
        $pack_zones = join('', $pack_zones);
        //if it's a substring of our product zones then we have a valid combination
        if (strpos($product_zones, $pack_zones) !== false) {
            $combinations[] = [$pack['name'], $packs[$i]['name']];
        }
    }
}

print_r($combinations);
  

результат: 1,3 (22223) ; 1,4 (2233) ; 2,4 (22233) ; 3,3 (2233)

Комментарии:

1. Спасибо! Позвольте мне адаптировать то, что вы мне присылаете, к моей структуре массива, и я расскажу вам 🙂