4

I need to get all the combinations and permutations of an array of array of values. See snippet for example:

$a = array(
    1,
    2
);
$b = array(
    'foo',
    'bar'
);

$params   = array();
$params[] = $a;
$params[] = $b;

// What to do to $params so I can get the following combinations/permutations?
// 1,foo
// 2,foo
// 1,bar
// 2,bar
// foo,1
// bar,1
// foo,2
// bar,2

Keep in mind that the $params can be any size and the items in it can also be any size.

3
  • 2
    Instead of actually processing this by counting the number of permutations I think it would be best to figure out a formula for the number of permutations based on the size of a and b. Or do you really need the sets? Commented Sep 14, 2011 at 22:19
  • Nevermind. I see now that you're not just looking for a count. Commented Sep 14, 2011 at 22:21
  • See also stackoverflow.com/questions/5751091/… Commented Sep 14, 2011 at 22:34

4 Answers 4

4
function all($array, $partial, &$result) {
    if ($array == array()) {
        $result[] = implode(',', $partial);
        return;
    }
    for($i=0; $i<count($array);$i++) {
        $e = $array[$i];
        $a = $array;
        array_splice($a, $i, 1);
        foreach($e as $v) {
            $p = $partial;
            $p[] = $v;
            all($a, $p, $result);
        }
    }
}

Test:

$a = array(1, 2, 3);
$b = array('foo', 'bar');
$c = array('a', 'b');
$params = array($a, $b, $c);

$result = array();
all($params, array(), $result);
print_r($result);

Note: if there is a chance for duplicates (arrays contain the same values) you can check for duplicates before inserting into the $result.

Sign up to request clarification or add additional context in comments.

1 Comment

yi_H - this is looking very promising. I will test. I'm not sure what you mean by duplicates. Do you mean if $a has the value 1, and $b also has 1 -- then there are duplicates? If so, for my purposes, they would not be considered duplicates.
1

Here is my solution. It should work with any number of associative arrays, even if they contained nested associative arrays.

<?php
    $a = array(1,2,3);
    $b = array('foo','bar','baz', array('other','other2',array('other3','other4')));
    $params = array();
    $params[] = $a;
    $params[] = $b;

    $elements = array();

    foreach($params as $param) {
     addElement($param,$elements);
    }

    function addElement($arg,&$result) {
        if(!is_array($arg)) {
            $result[] = $arg;
        } else {
            foreach($arg as $argArray) {
                addElement($argArray,$result);
            }
        }
    }

    for($i=0; $i<count($elements); $i++) {
        $curElement = $elements[$i];
        for($j=0; $j<count($elements); $j++) {
            if($elements[$j] != $curElement) {
                $final_results[] = $curElement.','.$elements[$j];
            }
        }
    }
    print_r($final_results);

?>

http://codepad.viper-7.com/XEAKFM

1 Comment

This will give you an array $final_results which contains all permutations and combinations
1

Here's a possible solution codepad...

$array = array(
    0   => array(
        'foo',
        'bar'
    ),
    1   => array(
        1,
        2,
        3
    ),
    2   => array(
        'x',
        'y',
        'z'
    ),
    3   => array(
        7,
        8,
        9
    )
);

array_permutations($array, $permutations);
print_r($permutations);

public function array_permutations($array, &$permutations, $current_key = 0, $current_subkey = 0)
{   
    if(!isset($array[$current_key][$current_subkey]))
    {
        return;
    }

    $current_val = $array[$current_key][$current_subkey];

    foreach($array as $array_key => $row)
    {
        foreach($row as $row_key => $sub_val)
        {
            if($array_key === $current_key)
            {
                if($row_key !== $current_subkey)
                {
                    $permutations[] = $current_val . ', ' . $sub_val;
                }
            }
            else 
            {
                $permutations[] = $current_val . ', ' . $sub_val;
            }
        }
    }

    $next_key = ($current_subkey == (count($array[$current_key]) - 1)) ? $current_key + 1 : $current_key;
    $next_subkey = ($next_key > $current_key) ? 0 : $current_subkey + 1;
    array_permutations($array, $permutations, $next_key, $next_subkey); 
}

Comments

0

Try this out, hope this helps

$a = array(
    1,
    2,
    4
);
$b = array(
    'foo',
    'bar',
    'zer'
);
$c = array(
    'aaa',
    'bbb'
);

$params   = array();
$params[] = $a;
$params[] = $b;
$params[] = $c;

$sizeofp = count($params);
for($i=0 ; $i < $sizeofp ; $i++){
    foreach ($params[$i] as $paramA) {
        for($j=0 ; $j < $sizeofp ; $j++){
            if($j == $i){
                continue;
            }
            foreach($params[$j] as $paramB){
                echo "\n".$paramA.",".$paramB;  
            }
        }
    }
}

3 Comments

the size of $params is unknown. This assumes $params contains 2 elements.
No this assumes that $params could be endless. Test it out! In fact, not only $params could be endless. Every $a, $b that you add to $params, could have any size. I will add the test source to my reply.
Ah! i get it you need to combine EVERY posible combination! The @yi_H reply is ok then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.