2

What I need

I need all possible pairs of n elements without duplicates. Let's say I've these arrays:

$arr1 = [2, 4, 6, 7];
$arr2 = [6, 5, 4, 11];
$arr3 = [22, 1, 5, 8];

$final = [
    'a' => $arr1, 
    'b' => $arr2, 
    'c' => $arr3
];

What I now need is:

$pairs = [
    'ab' => [$arr1, $arr2],
    'ac' => [$arr1, $arr3],
    'bc' => [$arr2, $arr3]
];

What I got

I come until this point:

function getPairs($array) {
    $n = count($array);

    $finalArray = [];
    $i = 0;
    foreach ($array as $a) {
        for ($x = $n-1; 0 <= $x; $x--) {
            if ($i != $x) {
                $finalArray[] = [$array[$i], $array[$x]];
            }
        }
        $i++;
    }

    return $finalArray;
}

And then:

$arr1 = [2, 4, 6, 7];
$arr2 = [6, 5, 4, 11];
$arr3 = [22, 1, 5, 8];

$merged = [$arr1, $arr2, $arr3];

$pairs = getPairs($merged);

There are two problems with my approach:

  1. The loop produces $x = 0, $i = 1 and later $i = 1, $x = 0, which results and a duplicated array.
  2. I don't get the keys (ab, ac, cb) with this.

Similiar to this question but with array keys: Get all the combinations of N elements of multidimensional array

Community
  • 1
  • 1
Julian
  • 1,380
  • 12
  • 28

3 Answers3

1

This code should work if I understand the task properly:

$a = [[2, 4, 6, 7],[6, 5, 4, 11],[22, 1, 5, 8]];
$result = [];
$n = count($a);

for($i = 0; $i < $n-1; $i++) {
    for($j = $i+1; $j < $n; $j++) {
        $result[(string)$i.(string)$j] = [$a[$i], $a[$j]];
    }
}

print_r($result);
Andrej
  • 7,474
  • 1
  • 19
  • 21
1

To avoid duplicates, guarantee that one member of the pair always has the "lower" key. This will avoid getting pairs ac and ca.

To get the letter keys you want, use array_keys() to extract the keys from the original arrays.

function getPairs($array) {
    $n = count($array);  
    $keys = array_keys($array);  
    $finalArray = [];
    $i = 0;
    foreach ($array as $a) {
        for ($x = $n-1; $i < $x; $x--) {
            $key1 = $keys[$i];
            $key2 = $keys[$x];
            $finalArray[$key1.$key2] = [$array[$key1], $array[$key2]];
        }
        $i++;
    }    
    return $finalArray;
}

Live demo

BeetleJuice
  • 39,516
  • 19
  • 105
  • 165
  • "always guarantee that one member of the pair always has the "lower" key." That was the missing piece. Thanks a lot, you are awesome! – Julian Sep 02 '16 at 19:34
0

Here is a "hybrid" of the other two answers:

$arr1 = [2, 4, 6, 7];
$arr2 = [6, 5, 4, 11];
$arr3 = [22, 1, 5, 8];

$final = [
    'a' => $arr1, 
    'b' => $arr2, 
    'c' => $arr3
];

$n = count($final);
$keys = array_keys($final);

$pairs = [];
for($i = 0; $i < $n-1; $i++) {
    for($j = $i+1; $j < $n; $j++) {
        $pairs[$keys[$i] . $keys[$j]] = [$final[$keys[$i]], $final[$keys[$j]]];
    }
}

print_r($pairs);
Paul Spiegel
  • 30,925
  • 5
  • 44
  • 53