#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. Спасибо! Позвольте мне адаптировать то, что вы мне присылаете, к моей структуре массива, и я расскажу вам 🙂