Search code examples
phparraysfunctionexplode

explode an array of delimited strings into two arrays


I have the following array:

Array
    (
        [0] => 10-7
        [1] => 11-3
        [2] => 11-7
        [3] => 12-3
        [4] => 12-7
        [5] => 13-3
        [6] => 13-7
        [7] => 14-3
        [8] => 14-7
        [9] => 15-7
    )

that I need to split into two arrays using "-" as delimiter:

Array
    (
        [0] => 10
        [1] => 11
        [2] => 11
        [3] => 12
        [4] => 12
        [5] => 13
        [6] => 13
        [7] => 14
        [8] => 14
        [9] => 15
    )

and

Array
    (
        [0] => 7
        [1] => 3
        [2] => 7
        [3] => 3
        [4] => 7
        [5] => 3
        [6] => 7
        [7] => 3
        [8] => 7
        [9] => 7
    )

Is there anything like array_explode that does what I want? or a combination of php array functions? I'd like to do this without going through my own for/each loop, if possible, or at least minimize having to reinvent the wheel when something (pseudo)in-built is already out there. I already did this with a for loop. But I can't shake the feeling that there's a more elegant way that smartly uses array functions or anything of that kind. Thanks so much, guys.

Additional info:

Not sure if it matters, but I'm actually after the unique values in the resulting two arrays:

Array
    (
        [0] => 10
        [1] => 11
        [2] => 12
        [3] => 13
        [4] => 14
        [5] => 15
    )

and

Array
    (
        [0] => 7
        [1] => 3
    )

The unique values don't need to be sorted, the keys may be preserved or not, and the legal values of the first array range from 0 to 23, while those of the second 1 to 7. However it's possible to have values other than these (0 to 23 and 1 to 7 or even undelimited stray strings or other data types beyond my control), which I would definitely want to throw out.


Solution

  • The magic bullet you're looking for is array_reduce(), e.g. (PHP 5.3+):

    list( $left, $right ) = array_reduce( $input,
      function( $memo, $item ) {
        list( $l, $r ) = explode( '-', $item );
        $memo[0][$l] = $memo[1][$r] = true;
        return $memo;
      },
      array( array(), array() )
    );
    
    var_dump( array_keys( $left ), array_keys( $right ) );
    

    You can see it in action here.

    With PHP <5.3 you'll have to declare the function ahead of time:

    function my_reducer( $memo, $item ) {
      list( $l, $r ) = // ...
      // ... as above ...
    }
    
    list( $left, $right ) = array_reduce(
      $input, 'my_reducer',
      array( array(), array() )
    );