3

I need to create a list of urls for all possible combinations from a set of filters/parameters.

Input

$data = array(
    array(
        'vehicle=car',
        'vehicle=bike',
        'vehicle=plane',
    ),
    array(
        'fruit=apple',
        'fruit=banana',
        'fruit=strawberry'
    ),
    array(
        'music=pop',
        'music=rock',
        'music=jazz'
    )
);

The generated items must have the parameters in alphabetical order.
For example:

INCORRECT: ?vehicle=bike&fruit=apple&music=rock

CORRECT: ?fruit=apple&music=rock&vehicle=bike

Output

?vehicle=car
?vehicle=bike
?vehicle=plane
?fruit=apple&vehicle=car
?fruit=banana&vehicle=car
?fruit=strawberry&vehicle=car
?fruit=apple&vehicle=bike
?fruit=banana&vehicle=bike
?fruit=strawberry&vehicle=bike
?fruit=apple&vehicle=plane
?fruit=banana&vehicle=plane
?fruit=strawberry&vehicle=plane
?fruit=apple&music=pop&vehicle=car
?fruit=apple&music=rock&vehicle=car
?fruit=apple&music=jazz&vehicle=car
?fruit=banana&music=pop&vehicle=car
?fruit=banana&music=rock&vehicle=car
?fruit=banana&music=jazz&vehicle=car
?fruit=strawberry&music=pop&vehicle=car
?fruit=strawberry&music=rock&vehicle=car
?fruit=strawberry&music=jazz&vehicle=car
?fruit=apple&music=pop&vehicle=bike
?fruit=apple&music=rock&vehicle=bike
?fruit=apple&music=jazz&vehicle=bike
?fruit=banana&music=pop&vehicle=bike
?fruit=banana&music=rock&vehicle=bike
?fruit=banana&music=jazz&vehicle=bike
?fruit=strawberry&music=pop&vehicle=bike
?fruit=strawberry&music=rock&vehicle=bike
?fruit=strawberry&music=jazz&vehicle=bike
?fruit=apple&music=pop&vehicle=plane
?fruit=apple&music=rock&vehicle=plane
?fruit=apple&music=jazz&vehicle=plane
?fruit=banana&music=pop&vehicle=plane
?fruit=banana&music=rock&vehicle=plane
?fruit=banana&music=jazz&vehicle=plane
?fruit=strawberry&music=pop&vehicle=plane
?fruit=strawberry&music=rock&vehicle=plane
?fruit=strawberry&music=jazz&vehicle=plane
?music=pop&vehicle=car
?music=rock&vehicle=car
?music=jazz&vehicle=car
?music=pop&vehicle=bike
?music=rock&vehicle=bike
?music=jazz&vehicle=bike
?music=pop&vehicle=plane
?music=rock&vehicle=plane
?music=jazz&vehicle=plane
?fruit=apple
?fruit=banana
?fruit=strawberry
?fruit=apple&music=pop
?fruit=apple&music=rock
?fruit=apple&music=jazz
?fruit=banana&music=pop
?fruit=banana&music=rock
?fruit=banana&music=jazz
?fruit=strawberry&music=pop
?fruit=strawberry&music=rock
?fruit=strawberry&music=jazz
?music=pop
?music=rock
?music=jazz

Is there anyone that could help me out with this. I've been struggling with it for two days now but I can't seem so find a correct solution. There are a lot of (almost) similar issues on Stackoverflow but none of them seems to solve/fit my problem.

[SOLVED] Here is the final working version based on Dusan Plavak's answer:

function createFilterCombinations($data, &$urls = array(), $index = 0, $query = false){
    $keys = array_keys($data);
    $_query = $query;
    if ($index == count($data)) {
        return;
    }
    for($i=0; $i < count($data[$keys[$index]]); $i++){
        $query = $_query;
        if($index == 0){
            $query = "?" . $data[$keys[$index]][$i];
        }else{
            if($query != "?"){
                $query .= "&" . $data[$keys[$index]][$i];
            }else{
                $query .= $data[$keys[$index]][$i];
            }
        }
        $urls[] = $query;
        createFilterCombinations($data, $urls, $index+1, $query);
    }
    if($index == 0){
        $query = "?";
    } else {
        $query = $_query;
    }
    createFilterCombinations($data, $urls, $index+1, $query);
}

function prepareArray($array){
    $newArray = array();
    foreach ($array as $subArray) {
        sort($subArray);
        $newArray[substr($subArray[0], 0, strpos($subArray[0], '='))] = $subArray;
    }
    ksort($newArray);
    return $newArray;
}

createFilterCombinations(prepareArray($data), $result);

var_dump($result);
Chris
  • 3,680
  • 6
  • 26
  • 43
  • 4
    +1 for pasting a proper PHP array that we can copy/paste rather than output of var_dump() – Cups Oct 04 '13 at 09:16

2 Answers2

2

So look at this http://codepad.org/TZWf7Vxd

and code for a time when link will be dead :D

<?php
$data = array(
    "vehicle" => array(
        'vehicle=car',
        'vehicle=bike',
        'vehicle=plane',
    ),
    "fruit" => array(
        'fruit=apple',
        'fruit=banana',
        'fruit=strawberry'
    ),
    "music" => array(
        'music=pop',
        'music=rock',
        'music=jazz'
    )
);
function hop($index, $query, $data){
  $keys = array_keys($data);
  if($index == count($data)){
      return;
  }
  $queryBackup = $query;
  for($i=0;$i<count($data[$keys[$index]]);$i++){
      $query = $queryBackup;
      if($index == 0){
          $query = "?".$data[$keys[$index]][$i];
      }else{
          if($query != "?"){
              $query .= "&".$data[$keys[$index]][$i];
          }else{
              $query .= $data[$keys[$index]][$i];
          }
      }
      echo $query."\n";
      hop($index+1, $query, $data);
  }
  if($index == 0){
     $query = "?";
  }else{
     $query = $queryBackup;
  }
  hop($index+1, $query, $data);
}

ksort($data);
hop(0,"", $data);
?>
Dusan Plavak
  • 4,457
  • 4
  • 24
  • 35
  • This is a start but it only displays 39 of 63 total possibilities. [Example of list](http://pastebin.com/XM2Nksyw) – Chris Oct 04 '13 at 10:02
  • Looks good, the most ideal situation would be if the 'hop' function would return an array instead of just echoing them. Is that possible? `$result = hop(0, "", $data);` – Chris Oct 04 '13 at 10:25
0

This is not a ready-made solution but you can use a function that returns an array combinations. I hope this could help You.

<?
$collect = false;
function combinations($arr, $temp_string, &$collect) {
        if ($temp_string != "")
            $collect[] = $temp_string;
        for ($i = 0; $i < sizeof($arr); $i++) {
            $arrcopy = $arr;
            $elem = array_splice($arrcopy, $i, 1);
            if (sizeof($arrcopy) > 0) {
                combinations($arrcopy, $temp_string . " " . $elem[0], $collect);
            } else {
                $collect[] = $temp_string . " " . $elem[0];
            }
        }
        return $collect;
    }
var_dump(combinations(array('abc', 'cde', 'fgi'),'',$collect));
?>

see WORKING CODE

Adam
  • 1,371
  • 2
  • 11
  • 12
  • I actually tried using this yesterday. Found it [here](http://stackoverflow.com/questions/10834393/php-how-to-get-all-possible-combinations-of-1d-array). This actually solves part of the problem. – Chris Oct 04 '13 at 09:42