Cartesian product of associative array showing key and value - PHP

292 views Asked by At

I have this array and I use it as INPUT:

Array
(
    [0] => Array
        (
            [11134] => 3.430
            [11131] => 2.720
            [11128] => 1.077
        )

    [1] => Array
        (
            [11135] => 2.381
            [11132] => 2.636
            [11129] => 2.920
        )

    [2] => Array
        (
            [11136] => 1.220
            [11133] => 2.550
            [11130] => 3.895
        )

)

I need to print the cartesian product of this array. I used the answer located here, but it doesn't really help me at all. I have modified the function Jon posted to make it faster (really just switched array_shift for array_pop so it wouldn't reindex the array as numeric):

function cartesian($input) {
    $result = array();

    while (list($key, $values) = each($input)) {
        if (empty($values)) {
            continue;
        }

        if (empty($result)) {
            foreach($values as $value) {
                $result[] = array($key => $value);
            }
        }
        else {

            $append = array();

            foreach($result as &$product) {
                $product[$key] = array_pop($values);

                $copy = $product;

                foreach($values as $item) {
                    $copy[$key] = $item;
                    $append[] = $copy;
                }

                $values[] = $product[$key];
            }

            $result = array_merge($result, $append);
        }
    }

    return $result;
}

The answer given prints the following array:

Array
(
    [0] => Array
        (
            [0] => 3.430
            [1] => 2.920
            [2] => 3.895
        )

    [1] => Array
        (
            [0] => 2.720
            [1] => 2.920
            [2] => 3.895
        )
    ...
)

which is not what I exactly want. THE DESIRED OUTPUT of the function is:

Array
(
    [0] => Array
        (
            [11134] => 3.430
            [11129] => 2.920
            [11130] => 3.895
        )

    [1] => Array
        (
            [11131] => 2.720
            [11129] => 2.920
            [11130] => 3.895
        )
    ...
)

I came up with how to make the first element of my new array to look like I need, the part of the code looks like this:

if (empty($result)) {
    foreach($values as $key => $value) {
        $result[] = array($key => $value);
    }
}

But that's where I'm stuck. I can't get the other values to grab their keys and display as the keys. The final array I managed to get looks like this.

Array
(
    [0] => Array
        (
            [11134] => 3.430
            [1] => 2.920
            [2] => 3.895
        )

    [1] => Array
        (
            [11131] => 2.720
            [1] => 2.920
            [2] => 3.895
        )
    ...
)
1

There are 1 answers

0
Useless Intern On BEST ANSWER

I think I got it, I googled "PHP combinations" (Assuming that a combination is similar to a Cartesian product, I think it is :s) and used this code as a base. The change I needed to make was instead of merging the arrays I had to use a union because according to the php manual:

Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.

and

If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator. ... The keys from the first array will be preserved. If an array key exists in both arrays, then the element from the first array will be used and the matching key's element from the second array will be ignored.

CODE:

<?php
 $temp = Array
(
    "0" => Array
        (
            "11134" => 3.430,
            "11131" => 2.720,
            "11128" => 1.077
        ),

    "1" => Array
        (
            "11135" => 2.381,
            "11132" => 2.636,
            "11129" => 2.920
        ),

    "2" => Array
        (
            "11136" => 1.220,
            "11133" => 2.550,
            "11130" => 3.895
        )

);


function get_combinations($arrays) {
    $result = array(array());
    foreach ($arrays as $property => $property_values) {
        $tmp = array();
        foreach ($result as $result_item) {
            foreach ($property_values as $property_key => $property_value) {
                $tmp[] = $result_item + array($property_key => $property_value);
            }
        }
        $result = $tmp;
    }
    return $result;
}

$combinations = get_combinations($temp);

var_dump($combinations);
?>

RESULTS:

array(27) {
  [0]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11135]=>
    float(2.381)
    [11136]=>
    float(1.22)
  }
  [1]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11135]=>
    float(2.381)
    [11133]=>
    float(2.55)
  }
  [2]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11135]=>
    float(2.381)
    [11130]=>
    float(3.895)
  }
  [3]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11132]=>
    float(2.636)
    [11136]=>
    float(1.22)
  }
  [4]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11132]=>
    float(2.636)
    [11133]=>
    float(2.55)
  }
  [5]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11132]=>
    float(2.636)
    [11130]=>
    float(3.895)
  }
  [6]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11129]=>
    float(2.92)
    [11136]=>
    float(1.22)
  }
  [7]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11129]=>
    float(2.92)
    [11133]=>
    float(2.55)
  }
  [8]=>
  array(3) {
    [11134]=>
    float(3.43)
    [11129]=>
    float(2.92)
    [11130]=>
    float(3.895)
  }
  [9]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11135]=>
    float(2.381)
    [11136]=>
    float(1.22)
  }
  [10]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11135]=>
    float(2.381)
    [11133]=>
    float(2.55)
  }
  [11]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11135]=>
    float(2.381)
    [11130]=>
    float(3.895)
  }
  [12]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11132]=>
    float(2.636)
    [11136]=>
    float(1.22)
  }
  [13]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11132]=>
    float(2.636)
    [11133]=>
    float(2.55)
  }
  [14]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11132]=>
    float(2.636)
    [11130]=>
    float(3.895)
  }
  [15]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11129]=>
    float(2.92)
    [11136]=>
    float(1.22)
  }
  [16]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11129]=>
    float(2.92)
    [11133]=>
    float(2.55)
  }
  [17]=>
  array(3) {
    [11131]=>
    float(2.72)
    [11129]=>
    float(2.92)
    [11130]=>
    float(3.895)
  }
  [18]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11135]=>
    float(2.381)
    [11136]=>
    float(1.22)
  }
  [19]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11135]=>
    float(2.381)
    [11133]=>
    float(2.55)
  }
  [20]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11135]=>
    float(2.381)
    [11130]=>
    float(3.895)
  }
  [21]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11132]=>
    float(2.636)
    [11136]=>
    float(1.22)
  }
  [22]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11132]=>
    float(2.636)
    [11133]=>
    float(2.55)
  }
  [23]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11132]=>
    float(2.636)
    [11130]=>
    float(3.895)
  }
  [24]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11129]=>
    float(2.92)
    [11136]=>
    float(1.22)
  }
  [25]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11129]=>
    float(2.92)
    [11133]=>
    float(2.55)
  }
  [26]=>
  array(3) {
    [11128]=>
    float(1.077)
    [11129]=>
    float(2.92)
    [11130]=>
    float(3.895)
  }
}