我有一个阵列,其中有不同的项目,例如衬衫,鞋子,领带,夹克等。这些项目中的每一个都可以有多个由其ID表示的设计。
$variations = array(
'shirts' => array('2'),
'shoes' => array('7', '3'),
'jackets' => array('1', '5')
);
现在我们正在寻找一种有效的方法来创建所有这些的不同变体。
## Required result ##
$result = array(
array('2','7','1'),
array('2', '7', '5'),
array('2','3','1'),
array('2','3','5')
);
任何帮助将不胜感激:)
编辑:我们目前的职能
function cartesian($input) {
$result = array();
while (list($key, $values) = each($input)) {
// If a sub-array is empty, it doesn't affect the cartesian product
if (empty($values)) {
continue;
}
// Seeding the product array with the values from the first sub-array
if (empty($result)) {
foreach($values as $value) {
$result[] = array($key => $value);
}
}
else {
// Second and subsequent input sub-arrays work like this:
// 1. In each existing array inside $product, add an item with
// key == $key and value == first item in input sub-array
// 2. Then, for each remaining item in current input sub-array,
// add a copy of each existing array inside $product with
// key == $key and value == first item of input sub-array
// Store all items to be added to $product here; adding them
// inside the foreach will result in an infinite loop
$append = array();
foreach($result as &$product) {
// Do step 1 above. array_shift is not the most efficient, but
// it allows us to iterate over the rest of the items with a
// simple foreach, making the code short and easy to read.
$product[$key] = array_shift($values);
// $product is by reference (that's why the key we added above
// will appear in the end result), so make a copy of it here
$copy = $product;
// Do step 2 above.
foreach($values as $item) {
$copy[$key] = $item;
$append[] = $copy;
}
// Undo the side effecst of array_shift
array_unshift($values, $product[$key]);
}
// Out of the foreach, we can add to $results now
$result = array_merge($result, $append);
}
}
return $result;
}
答案 0 :(得分:0)
虽然我同意你的问题下面的评论,但我实现了基于生成器的解决方案,因此无论如何我都可以分享它:
$variations = array(
'shirts' => array('2'),
'shoes' => array('7', '3'),
'jackets' => array('1', '5')
);
var_dump(iterator_to_array(cartesian($variations), false));
function cartesian($lists, $product = [])
{
if (empty($product)) {
// first run, reverse array for array_pop and remove empty lists
$lists = array_reverse(array_filter($lists, 'count'));
}
$curr = array_pop($lists);
foreach ($curr as $c) {
if (empty($lists)) {
yield array_merge($product, [$c]);
} else {
yield from cartesian($lists, array_merge($product, [$c]));
}
}
}
答案 1 :(得分:0)
我就这样做了
$parameters = array(
'shirts' => array('2'),
'shoes' => array('7', '3'),
'jackets' => array('1', '5')
);
$arPhrases = $parameters[0];
for ($i = 1; $i < count($parameters); $i++) {
$notFullCount = count($arPhrases);
foreach ($arPhrases as $phrase) {
foreach ($parameters[$i] as $newPart) {
$arPhrases[] = $phrase." ".$newPart;
}
}
$arPhrases = array_slice($arPhrases, $notFullCount);
}