views:

174

answers:

4

I have pairs of items in an PHP array. Example:

<?php
$elements = array(
 'tiger'=>'lion',
 'car'=>'bike',
 'lion'=>'zoo',
 'truck'=>'plane'
);
?>

Now I want to combine these items so that all items which are connected in any way go to one group. Continuation of the example above:

<?php
$groups = array(
 0=>array('tiger', 'lion', 'zoo'),
 1=>array('car', 'bike'),
 2=>array('truck', 'plane'
);
?>

Is this understandable? How could I achieve this?

I'm looking for a function which does this.

A: 

The idea is simple:

  1. Create a new array to hold your groups
  2. Loop over the item array
  3. Check if the group for the item exists in the group array - if it does not, create it
  4. Put item in group
Jani Hartikainen
A: 

hello,
http://pl.php.net/manual/en/function.array-walk.php
this should help. Please let me know if you need 'full'
code of the function (Im thinking about funtion called on each element of the array).

--
Regards,
Robert

Robert
+3  A: 
<?php

$elements = array(
    'tiger' => 'lion',
    'car' => 'bike',
    'lion' => 'zoo',
    'truck' => 'plane'
);

$groups = array();

foreach ($elements as $key => $val) {
    $appended = false;
    foreach ($groups as &$group) {
        if ($group[0] == $key) {
            array_unshift($group, $val);
            $appended = true;
            break;
        }
    }
    if (!$appended) {
        $groups[] = array($val, $key);
    }
}

var_dump($groups);

Gives:

array(3) {
  [0]=>
  array(3) {
    [0]=>
    string(3) "zoo"
    [1]=>
    string(4) "lion"
    [2]=>
    string(5) "tiger"
  }
  [1]=>
  &array(2) {
    [0]=>
    string(4) "bike"
    [1]=>
    string(3) "car"
  }
  [2]=>
  array(2) {
    [0]=>
    string(5) "plane"
    [1]=>
    string(5) "truck"
  }
}
Ben James
Your sub-arrays are all in reverse order, I'm not sure if that matters though.
Justin Johnson
Thank you very much, the order doesn't matter. :)
+2  A: 

Here's an O(n) solution:

$elements = array(
    'tiger' => 'lion',
    'car'   => 'bike',
    'lion'  => 'zoo',
    'truck' => 'plane'
);
$groups = array();
$sub    = array();
$ignore = array();

foreach ( $elements as $key=>$value ) {
    if ( isset($ignore[$key]) ) {
     continue;
    }

    $sub = array($key, $value);

    if ( isset($elements[$value]) ) {
     $ignore[$value] = 1;
     $sub[]          = $elements[$value];
    }

    $groups[] = $sub;
}

print_r($groups);

Result:

Array
(
    [0] => Array
        (
            [0] => tiger
            [1] => lion
            [2] => zoo
        )

    [1] => Array
        (
            [0] => car
            [1] => bike
        )

    [2] => Array
        (
            [0] => truck
            [1] => plane
        )

)
Justin Johnson
Thank you very much, the order doesn't matter. :)