1

I need some help wrapping my head around a problem. I have an array filled with other arrays. I need to:

  1. Loop through the entire array and build a new array called finalOptions
  2. Each iteration of the loop will take a new SearchIndex and apply the other paramenters

i.e

SearchIndex => SportingGoods
MinPercentageOff => 50
MinimumPrice => 1
ItemPage => 1
Sort => salesrank
BrowseNode => 2342470011

THEN:

Final array should contain data like this

SearchIndex => SportingGoods
MinPercentageOff => 60
MinimumPrice => 100
ItemPage => 2
Sort => salesrank
BrowseNode => 3403201

Basically, I'm creating a new array and sending it to another method that will execute a call to an API and return a result, then doing it again until my array options are complete.

This might not be the way to go and I'm looking for suggestions/pseudo code on an approach. Here is the basics of what I have so far:

Starting with this code

$allOptions = array(
    "SearchIndex"           => array("SportingGoods", "Tools"),
    "MinPercentageOff"      => array("50", "60", "70"),
    "MinimumPrice"          => array("1", "100", "1000"),
    "ItemPage"              => array("1", "2"),
    "Sort"                  => array("salesrank")
    "BrowseNode"            => array(
                                    "SportingGoods" => array("2342470011", "3403201"),
                                    "Tools"         => array("511364")
                            )
)

$finalOptions = array();

foreach($allOptions as $options){
    foreach($options["SearchIndex"] as $searchIndex){
        $finalOptions[] = "SearchIndex" => $searchIndex[]
    }


    $this->itemSearch($finalOptions);
}

EDIT

The arrays will contain more values. i.e "ItemPage" => array("1", "2"), will have 1 - 10. The others will have more values as well.

Paul Dessert
  • 6,363
  • 8
  • 47
  • 74
  • 2
    Can you make a bit clearer what you are starting with and what you want to end up with? – Mike Miller Jun 23 '15 at 06:17
  • @MikeMiller I'm starting with the array `$allOptions` and I want to loop through it and build a new array called `$finalOptions`. `$finalOptions` should include an array similar to my second code block above. Hopefully that helps. – Paul Dessert Jun 23 '15 at 06:19
  • How do you differentiate number of values within your array. `Example : SearchIndex ` contains `2 array values ` while the right next contains `three` – Narendrasingh Sisodia Jun 23 '15 at 06:20
  • @Uchiha that's part of where I'm stuck. I'm not sure how to handle that. I'm open to other ideas – Paul Dessert Jun 23 '15 at 06:22
  • Might be you can differentiate those from query you were making – Narendrasingh Sisodia Jun 23 '15 at 06:23
  • Do you want to generate all combinations possible for that ? – viral Jun 23 '15 at 06:24
  • @Viral Yes, until `BrowseNode`. Then at that point, use the browse nodes that match the `SearchIndex` for the current iteration. – Paul Dessert Jun 23 '15 at 06:25
  • So you are only able to relate each sub arrays values by the index order? So all first values go together etc? – Mike Miller Jun 23 '15 at 06:25
  • @MikeMiller The realtionship doesn't really matter other than `searchIndex` and `browseNode` those need to match – Paul Dessert Jun 23 '15 at 06:26
  • How do you know which MinPercentageOff relates to which BrowseNode? As another commenter said can you show your query as this might be easier solved further up the code chain – Mike Miller Jun 23 '15 at 06:28
  • @MikeMiller Each `minPercentageOff` will be used on each `BrowseNode`. I'll see if I can add more code... – Paul Dessert Jun 23 '15 at 06:29
  • @MikeMiller I think it will be more confusing if I add more code. It's a large block of code that basically takes the new array created here and appends it to another array. That method makes a call to Amazon, returns a signed URL and then parses the XML. – Paul Dessert Jun 23 '15 at 06:36

1 Answers1

1

From the given array it will produce 54 possible combinations as you described.

Also you need to make sure you have array in $allOptions['BrowseNode'] indexed as each value of $allOptions['SearchIndex']. Otherwise it will produce error.

Cartesian function from here.

$allOptions = [
    "SearchIndex"           => ["SportingGoods", "Tools"],
    "MinPercentageOff"      => ["50", "60", "70"],
    "MinimumPrice"          => ["1", "100", "1000"],
    "ItemPage"              => ["1", "2"],
    "Sort"                  => ["salesrank"],
    "BrowseNode"            => ["SportingGoods" => ["2342470011", "3403201"], "Tools" => ["511364"] ] ];


$finalOptions = $allOptions; // copy our initial $allOptions array

unset($finalOptions['BrowseNode']); // deal with BrowseNode key later with custom iterator

$cartesian_product = cartesian($finalOptions); // find cartesian except BrowseNode

foreach($cartesian_product as $cartesian) // each member of cartesian product will iterate here
{
    foreach($allOptions['BrowseNode'][$cartesian['SearchIndex']] as $possible)
    /*
        We have unset the BrowseNode, so need to refer original $allOptions array for BrowseNode,
        In every cartesian product, we will get $cartesian['SearchIndex'] and it will contain either
        'SportingGoods' or 'Tools' , so in our original array, look for 'BrowseNode' value, having key
        same as $cartesian['SearchIndex'].

        $allOptions['BrowseNode'][$cartesian['SearchIndex']] <---- is similar to below two lines

        $key = $cartesian['SearchIndex'];
        $allOptions['BrowseNode'][$key];

        Finally iterate through $allOptions['BrowseNode'][$cartesian['SearchIndex']] will iterate as many times,
        as many values there are
    */
    {
        $cartesian['BrowseNode'] = $possible; // assign the long waited key here to 'BrowseNode'
        var_dump($cartesian); // here you can do $this->itemSearch($cartesian);
    }
}

function cartesian($input) {

    $input = array_filter($input);
    /*  
        will renove any false values in input array,
        in our array's case, it will do nothing.
    */
    $result = [[]];

    foreach ($input as $key => $values) {
        $append = [];

        foreach($result as $product) {
            foreach($values as $item) {

                $product [$key] = $item;
                $append [] = $product;

            }
        }

        $result = $append;
    }

    return $result;
}
Community
  • 1
  • 1
viral
  • 3,724
  • 1
  • 18
  • 32
  • Thanks for taking the time to write this out! So, the `cartesian` function will run, then the `foreach` loop gathers all possible combinations of `browseNodes` correct? – Paul Dessert Jun 23 '15 at 06:58
  • yes, Absolutely. Here `2 SportingGoods x 3 x 3 x 2 x 1` + `1 Tools x 3 x 3 x 2 x 1` = `54` – viral Jun 23 '15 at 07:11
  • Beautiful! This is exactly what I was looking for. Thanks again. – Paul Dessert Jun 23 '15 at 07:12
  • Two more questions: 1. What is `array_filter` used for here `$input = array_filter($input);` and, can you explain this: `foreach($allOptions['BrowseNode'][$cartesian['SearchIndex']] as $possible)`. I'm not clear on `$allOptions['BrowseNode'][$cartesian['SearchIndex']]` is that comparing the values of the array keys? – Paul Dessert Jun 23 '15 at 07:57
  • 1
    I took the function from another [SO post here](http://stackoverflow.com/a/15973172/3113793), but i can explain what it is doing, i will update my question with edits, i need some time for that as i am bad at explaining. – viral Jun 23 '15 at 08:03
  • Thanks again! I appreciate it. – Paul Dessert Jun 23 '15 at 17:44