Ana Ban
Ana Ban

Reputation: 1405

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.

Upvotes: 1

Views: 2145

Answers (6)

mickmackusa
mickmackusa

Reputation: 47864

Okay, if "The unique values don't need to be sorted, the keys may be preserved or not", then I am going to apply the values to the result arrays as both keys and values to ensure uniqueness without any more function calls after the initial loop.

You can use explode() or sscanf(). explode() has a simpler syntax and only requires the glue substring, whereas sscanf() must parse the whole string and therefore needs a more complicated pattern to match with.

If you didn't need uniqueness, you could simply use:

$hours = [];
$days = [];
foreach ($array as $item) {
    sscanf($item, '%d-%d', $hours[], $days[]);
}

or

$hours = [];
$days = [];
foreach ($array as $item) {
    [$hours[], $days[]] = explode('-', $item);
}

To ensure uniqueness, just use the isolated values as keys as well.

sscanf() allows you to cast the parsed values directly to integers (Demo)

$hours = [];
$days = [];
foreach ($array as $item) {
    [0 => $hour, 1 => $day, 0 => $hours[$hour], 1 => $days[$day]] = sscanf($item, '%d-%d');
}

explode() will only produce string-type values. (Demo)

$hours = [];
$days = [];
foreach ($array as $item) {
    [0 => $hour, 1 => $day, 0 => $hours[$hour], 1 => $days[$day]] = explode('-', $item);
}

All of the above snippets rely on "array destructuring" syntax instead of calling list(). If you are wondering why the keys are repeated while destructuring, see this post.

Upvotes: 0

Jordan Running
Jordan Running

Reputation: 106027

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() )
);

Upvotes: 3

Vishal
Vishal

Reputation: 2181

Try:

foreach($old_array as $array){
    $new_2d_array = explode('-', $array);
    $new_array_1[] = $new_2d_array[0];
    $new_array_2[] = $new_2d_array[1];  
}
$new_array_1 = array_unique($new_array_1);
$new_array_2 = array_unique($new_array_2);

Upvotes: 0

Andrius Naruševičius
Andrius Naruševičius

Reputation: 8578

http://codepad.org/TpVUIhM7

<?php
    $array = array('7-10','7-11','5-10');
    foreach($array as $a){list($x[], $y[]) = explode("-", $a);}
    print_r(array_unique($x));
    print_r(array_unique($y));
?>

Upvotes: 2

Ikke
Ikke

Reputation: 101221

As far as I know, there is no suitable PHP function that you can use in this situation.

Functions like array_walk() and array_map() result in a single array, not in multiple arrays.

You said you already have tried a sollution with a loop, but for the sake of helping, here is how I would solve this:

//$data contains the array you want to split
$firstItems = array();
$secondItems = array();

foreach($data as $item)
{
    list($first, $second) = explode('-', $item, 2);
    $firstItems[$first] = true;
    $secondItems[$second] = true;    
}

//Now you can get the items with array_keys($firstItems) and array_keys($secondItems);

I'm treating the PHP array as a set by setting the keys instead of the values. This makes that you don't have to use array_unique() to get the unique items.

Upvotes: 0

pinaldesai
pinaldesai

Reputation: 1815

Here Is your Solution, Try to implement following code.

Should work for you.

$main_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',
        );

foreach($main_array as $key=>$value)
{
    $arr_value      =   explode('-',$value);
    $arr_temp1[]    =   $arr_value[0];
    $arr_temp2[]    =   $arr_value[1];  
}
$arr_temp1_unique   = array_unique($arr_temp1);
$arr_temp2_unique   = array_unique($arr_temp2);


print "<pre>";
print_r($main_array);
print_r($arr_temp1);
print_r($arr_temp2);

print_r($arr_temp1_unique);
print_r($arr_temp2_unique);
print "</pre>";

Upvotes: 0

Related Questions