8

I need to divide an array into two arrays.

One array will contain all positive values (and zeros), the other all negative values.

Example array:

$ts = [7,-10,13,8,0,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7];

Negatives result array:

[-10,-7.2,-12,-3.7,-9.6,-1.7,-6.2];

Non-negatives result array:

[7,13,8,0,4,3.5,6.5,7];
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Ripa Saha
  • 2,532
  • 6
  • 27
  • 51

5 Answers5

13

Without using any array functions..

Pretty straightforward. Just loop through the array and check if the number is less than 0, if so , push it in the negative array else push it in the positive array.

<?php
$ts=array(7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7);
$pos_arr=array(); $neg_arr=array();
foreach($ts as $val)
{
    ($val<0) ?  $neg_arr[]=$val : $pos_arr[]=$val;
}
print_r($pos_arr);
print_r($neg_arr);

OUTPUT :

Array
(
    [0] => 7
    [1] => 13
    [2] => 8
    [3] => 4
    [4] => 3.5
    [5] => 6.5
    [6] => 7
)
Array
(
    [0] => -10
    [1] => -7.2
    [2] => -12
    [3] => -3.7
    [4] => -9.6
    [5] => -1.7
    [6] => -6.2
)
Community
  • 1
  • 1
Shankar Narayana Damodaran
  • 68,075
  • 43
  • 96
  • 126
8

You can use array_filter function,

$positive = array_filter($ts, function ($v) {
  return $v > 0;
});

$negative = array_filter($ts, function ($v) {
  return $v < 0;
});

Note: This will skip values with 0, or you can just change condition to >=0 in positive numbers filter to considered in positive group.

DEMO.

Rikesh
  • 26,156
  • 14
  • 79
  • 87
4

The most elegant is to use phps array_filter() function:

<?php

$ts = [ 7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7 ];  

print_r( array_filter( $ts, function( $val ) { return   (0>$val); } ) );
print_r( array_filter( $ts, function( $val ) { return ! (0>$val); } ) );

?>

If you are still using an older php version you need some longer implementation:

<?php

$ts = array( 7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7 );  

print_r( array_filter( $ts, create_function( '$val', 'return   (0>$val);' ) ) );
print_r( array_filter( $ts, create_function( '$val', 'return ! (0>$val);' ) ) );

?>
arkascha
  • 41,620
  • 7
  • 58
  • 90
4

Food for thought, you could write a generic function that splits an array based on a boolean result:

// splits an array based on the return value of the given function
// - add to the first array if the result was 'true'
// - add to the second array if the result was 'false'
function array_split(array $arr, callable $fn)
{
    $a = $b = [];
    foreach ($arr as $key => $value) {
        if ($fn($value, $key)) {
           $a[$key] = $value;
        } else {
           $b[$key] = $value;
        }
    }
    return [$a, $b];
}

list($positive, $negative) = array_split($ts, function($item) {
    return $item >= 0;
});
print_r($positive);
print_r($negative);

Demo

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
0

Rather than declaring two arrays, I recommend declaring one array with two subarrays. You can either give the subarrays an index of 0 or 1 depending on the conditional evaluation with zero, or you can go a little farther by declaring a lookup array to replace the integer key with an expressive word.

Regardless of if you choose to create one array or two arrays, you should only make one loop over the input array. Making two loops or by calling array_filter() twice is needlessly inefficient.

Code: (Demo)

$ts = [7,-10,13,8,4,-7.2,-12,-3.7,3.5,-9.6,6.5,-1.7,-6.2,7];
const KEY_NAMES = [0 => 'negative', 1 => 'non-negatuve'];

$result = [];
foreach ($ts as $v) {
    $result[KEY_NAMES[$v >= 0]][] = $v;
}

var_export($result);

Output:

array (
  'non-negatuve' => 
  array (
    0 => 7,
    1 => 13,
    2 => 8,
    3 => 4,
    4 => 3.5,
    5 => 6.5,
    6 => 7,
  ),
  'negative' => 
  array (
    0 => -10,
    1 => -7.2,
    2 => -12,
    3 => -3.7,
    4 => -9.6,
    5 => -1.7,
    6 => -6.2,
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136