У меня есть «атрибуты» из базы данных. Каждый атрибут имеет много значений. Теперь я хочу смешать эти значения для создания уникальных комбинаций.
пример ввода:
$a = array(
35=>array('green','red','brown'),
36=>array('fox','house','dog')
);
вывод — все возможные комбинации элементов второго измерения. Пример вывода ниже:
$output = array(
array(35=>'green',36=>'fox'),
array(35=>'green',36=>'house'),
array(35=>'green',36=>'dog'),
array(35=>'red',36=>'fox'),
array(35=>'red',36=>'house'),
array(35=>'red',36=>'dog'),
array(35=>'brown',36=>'fox'),
array(35=>'brown',36=>'house'),
array(35=>'brown',36=>'dog'),
);
моя функция без повторений:
function myfunction($a){
$keys = array_keys($a);
$result = array();
if(count($keys)==0){
$result = array();
}
elseif(count($keys)==1){
$k = $keys[0];
foreach($a[$k] as $v){
$result[] = array($k=>$v);
}
}
elseif(count($keys)==2){
$k1 = $keys[0];
$k2 = $keys[1];
foreach($a[$k1] as $v1){
foreach($a[$k2] as $v2){
$result[] = array($k1=>$v1,$k2=>$v2);
}
}
}
elseif(count($keys)==3){
$k1 = $keys[0];
$k2 = $keys[1];
$k3 = $keys[2];
foreach($a[$k1] as $v1){
foreach($a[$k2] as $v2){
foreach($a[$k3] as $v3){
$result[] = array($k1=>$v1,$k2=>$v2,$k3=>$v3);
}
}
}
}
else{
throw new Exception('To much keys', 1);
}
return $result;
}
Это должно работать для вас:
Так что же делает этот код?
1. Сколько существует комбинаций?
Итак, сначала вопрос, сколько комбинаций существует, и ответ на этот вопрос: вы должны умножить количество каждого массива друг на друга.
Итак (с = сумма1):
смассив 1 * смассив 2 * … * смассив n
И конкретно для вашего примера:
смассив 1 * смассив 2 знак равно 3 * 3 знак равно 9
*1 И если вам интересно, почему я выбрал c
на сумму, из-за функции count()
в php
2. Получение всех комбинаций
Как мы теперь получим все комбинации с длиной суммы всех массивов?
Ну, довольно просто, мы просто перебираем все комбинации (в начале просто пустая комбинация ([] == array()
)), который у нас уже есть со следующим массивом, пока мы не получим желаемую длину, которую мы хотим, в этом случае последнюю итерацию последнего массива.
Итак, в качестве примера:
Array with the elements (Empty array is '[]'):
[
[1, 2],
[3, 4]
]
//new combinations for the next iteration
|
array NAN*:
Combinations:
- [] | -> []
|
array 1 [1,2]: -------------
| |
Combinations: v v
- [] + 1 | -> [1]
- [] + 2 | -> [2]
|
array 2 [3,4]: -------------
| |
Combinations: v v
- [] + 3 | -> [3]
- [] + 4 | -> [4]
- [1] + 3 | -> [1,3]
- [1] + 4 | -> [1,4]
- [2] + 3 | -> [2,3]
- [2] + 4 | -> [2,4]
//^ All combinations here
* NAN: не номер
Итак, как вы можете видеть в приведенном выше примере, у нас теперь есть все комбинации с длиной количества всех массивов, которые у нас есть.
Но чтобы получить только комбинации с желаемой длиной, мы перезаписываем массив результатов каждую итерацию, чтобы в конце в массиве результатов были только комбинации с ожидаемой длиной.
код:
<?php
$data = [
35 => ["green", "red", "brown"],
36 => ["fox", "house", "dog"]
];
$combinations = [[]];
$comKeys = array_keys($data);for ($count = 0; $count < count($comKeys); $count++) {
$tmp = [];
foreach ($combinations as $v1) {
foreach ($data[$comKeys[$count]] as $v2)
$tmp[] = $v1 + [$comKeys[$count] => $v2];
}
$combinations = $tmp;
}
print_r($combinations);
?>
выход:
Array
(
[0] => Array
(
[35] => green
[36] => fox
)
[1] => Array
(
[35] => green
[36] => house
)
[2] => Array
(
[35] => green
[36] => dog
)
[3] => Array
(
[35] => red
[36] => fox
)
[4] => Array
(
[35] => red
[36] => house
)
[5] => Array
(
[35] => red
[36] => dog
)
[6] => Array
(
[35] => brown
[36] => fox
)
[7] => Array
(
[35] => brown
[36] => house
)
[8] => Array
(
[35] => brown
[36] => dog
)
)
Вы можете использовать это: https://gist.github.com/jwage/11193216
или же
используйте код ниже:
<?php
$attributes = [
[
'P', 'M', 'G', 'XG'
],
[
'Vermelho', 'Amarelo', 'Verde'
],
];function array_mix($leftItems, $rightItems)
{
$results = [];
foreach ($leftItems as $leftItem) {
foreach ($rightItems as $key => $rightItem) {
$results[] = array_merge((array) $leftItem, (array) $rightItem);
}
}
return $results;
}
$y = $attributes[0];
foreach($attributes as $key => $attrs) {
if(isset($attributes[$key + 1]) && is_array($attributes[$key + 1])) {
$y = array_mix($y, $attributes[$key + 1]);
}
}
var_dump($y);