5

Say i start with a simple array (which could be theoretically of any length):

$ids  = array(1,2,3,4);

What it the best solution for splitting this array into an array of unique pairs like:

$pair[0] = array(1,2);
$pair[1] = array(1,3);
$pair[2] = array(1,4);
$pair[3] = array(2,3);
$pair[4] = array(2,4);
$pair[5] = array(3,4);

6 Answers 6

3

The simplest solution is to use a nested loop and build combinations as you go, although note that the complexity here is O(n2).

$ids = array(1,2,3,4,4);
$combinations = array();

$ids = array_unique($ids); // remove duplicates
$num_ids = count($ids);

for ($i = 0; $i < $num_ids; $i++)
{
  for ($j = $i+1; $j < $num_ids; $j++)
  {
    $combinations[] = array($ids[$i], $ids[$j]);
  }
}

See this in action at http://www.ideone.com/9wzvP

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

6 Comments

You could get away with the in_array check by doing array_unique on $ids. And you can also speed it up by counting $ids as a precondition before the loops (since it's not going to change). I only mention these since you do mention the complexity...
@ircmaxell True about counting $ids first, though that won't affect the complexity. I don't think you can use array_unique ahead of time though... it depends on the OP's goal. ie. if $ids = array(1,2,3,3), should [3,3] be a result?
I can confirm that 3,3 shouldn't be a result
Counting $ids won't affect complexity significantly (since it's an O(1) function), but in_array is not O(1) (I'm not positive, but I think it may be O(n), but I may be mistaken), so that would affect complexity. And yes, it does depend on the goal (The OP is not asking for a true cartesian product, but a limited one (and I can't remember the name for it off the top of my head))...
@ircmaxell I'd think array_unique is probably O(n^2) as well, no? (See stackoverflow.com/questions/478002/…)
|
1

Probably not the best solution

$ids  = array(1,2,3,4);

$pairs = array();
foreach($ids as $key => $data){
    foreach($ids as $subkey => $subdata){
        if( $subkey != $key){
            if(!in_array(array($subdata, $data) , $pairs) ){
                $pairs[] = array($data, $subdata);
            }
        }
    }
}

Anyway it works

Comments

1

Fixed from my initial jump-the-gun suggestion of array_chunk()

Try this instead:

$ids  = array(1, 2, 3, 4);
$out = array();

while ($item = array_shift($ids)) {
    foreach ($ids as $key=>$value) {
        $out[] = array($item, $value);
    }
}

1 Comment

array_chunk won't do what the OP wants, look at the example output. OP wants combinations.
1

Sweet solution, Nev Stokes! I changed the 'while' statement to avoid the loop from breaking when one of the values is 0:

$ids  = array(0, 1, 2, 3, 4);
$out = array();

while ( !is_null( $item = array_shift($ids) )  ) {
    foreach ($ids as $key=>$value) {
        $out[] = array($item, $value);
    }

}

Comments

0
$ids  = array(1,2,3,4);
$result=array();
foreach($ids as $value_1)
{
  foreach($ids as $value_2)
  {
     if($value_1 !=$value_2)
     {
       $result[]=array($value_1,$value_2);
     }
   }
}
echo "<pre>";
print_r($result);

Comments

-1

$pair = array_chunk($ids, 2);

http://www.php.net/manual/en/function.array-chunk.php

1 Comment

He's looking for a cartesian product, not splitting the array into smaller chunks...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.