0

Here is a var_dump of my array:

array(6) {
    [0]=> string(4) "quack"
    ["DOG"]=> string(4) "quack"
    [1]=> string(4) "quack"
    ["CAT"]=> string(4) "quack"
    [2]=> string(4) "Aaaaarrrrrggggghhhhh"
    ["CAERBANNOG"]=> string(4) "Aaaaarrrrrggggghhhhh"
}

(just for fun I've included two puns in this code, try and find them!)

How do I split this array into two arrays, one containing all the quacks; the other Aaaaarrrrrggggghhhhh?


Note that it won't always be in consecutive order, so was thinking maybe nested hashmaps, something like:

  1. Check if (isset($myarr['$found_val']))
  2. Append that array if found
  3. Else create that place with a new array

But not sure how the arrays are implemented, so could be O(n) to append, in which case I'd need some other solution...

Community
  • 1
  • 1
stackoverflowuser95
  • 1,992
  • 3
  • 20
  • 30

3 Answers3

1

You can just group them based on values and store the keys

$array = array(0 => "quack","DOG" => "quack",1 => "quack","CAT" => "quack",2 => "Aaaaarrrrrggggghhhhh","CAERBANNOG" => "Aaaaarrrrrggggghhhhh");

$final = array();
foreach ( $array as $key => $value ) {
    if (! array_key_exists($value, $final)) {
        $final[$value] = array();
    }
    $final[$value][] = $key;
}

var_dump($final);

Output

array
  'quack' => 
    array
      0 => int 0
      1 => string 'DOG' (length=3)
      2 => int 1
      3 => string 'CAT' (length=3)
  'Aaaaarrrrrggggghhhhh' => 
    array
      0 => int 2
      1 => string 'CAERBANNOG' (length=10)
Baba
  • 94,024
  • 28
  • 166
  • 217
  • 1
    +1 beat me to it :) however I'd do `$final[$value]=array($key);` to be slightly shorter - in place of the else. ps. you have two var_dumps :) – Pebbl Oct 13 '12 at 11:44
  • @pebbl sorry about that ... :) – Baba Oct 13 '12 at 11:45
  • 2
    I would rewrite that either way. To prevent doing this `$final[$value][] = $key;` multiple times in the code. Just create the element if array key does not exist and always just append it. – PeeHaa Oct 13 '12 at 11:46
1

Just in case anyone wants to do this in a more of and odd way:

Updated with air4x's idea of using only a single item array, instead of array_fill(0,count($a),$v). Makes it's much more sensible.

$a = array(
  0 => "quack",
  "DOG" => "quack",
  1 => "quack",
  "CAT" => "quack",
  2 => "Aaaaarrrrrggggghhhhh",
  "CAERBANNOG" => "Aaaaarrrrrggggghhhhh"
);

$b = array();
foreach( array_unique(array_values($a)) as $v ) {
  $b[$v] = array_intersect($a, array($v));
}

echo '<xmp>';
print_r($b);

Totally not optimal - difficult to read - but still interesting :)

Pebbl
  • 34,937
  • 6
  • 62
  • 64
1

Try this

$quacks_arr = array_intersect($your_array, array('quack'));
$argh_arr   = array_intersect($your_array, array('Aaaaarrrrrggggghhhhh'));

If you want to sort them, then just do ksort

ksort($quacks_arr);
ksort($argh_arr);
air4x
  • 5,618
  • 1
  • 23
  • 36
  • +1 I had not realised that I could use just a one item array for `array_intersect`. I'd falsely assumed it would compare against every key offset. nice. – Pebbl Oct 13 '12 at 14:24