2017-05-18 4 views
0

Ich habe ein Array, das verschiedene Elemente hat, wie Hemden, Schuhe, Krawatten, Jacken usw. Und jedes dieser Elemente kann mehrere Designs mit ihren IDs haben.Erhalten Sie einzigartige Variationen von mehreren Arrays

$variations = array(
    'shirts' => array('2'), 
    'shoes' => array('7', '3'), 
    'jackets' => array('1', '5') 
); 

Jetzt suchen wir nach einer effizienten Möglichkeit, verschiedene Variationen von all diesen zu erstellen.

## Required result ## 
$result = array(
    array('2','7','1'), 
    array('2', '7', '5'), 
    array('2','3','1'), 
    array('2','3','5') 
); 

Jede mögliche Hilfe geschätzt :)

EDIT: Unsere aktuelle Funktion

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; 
} 
+2

Stehen Sie irgendeinem bestimmten Kodierungsproblem gegenüber, oder bitten Sie einfach jemanden, den Job zu tun? –

+0

wir suchen nach besserer Code. Hier ist unsere aktuelle Implementierung. –

+0

Es wäre fair zu erwähnen Credits für "Ihre" Funktion ausgeliehen von http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays –

Antwort

0

Während ich mit Kommentaren unter Ihrer Frage stimme ich Generator-basierte Lösung für Spaß, damit ich umgesetzt kann es trotzdem teilen:

$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])); 
       } 
     } 
} 
0

Das ist, wie ich es tat

$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); 
} 
Verwandte Themen