Elo
Elo

Reputation: 53

How to remove date from an array having a same year, month and day with higher time?

In PHP how to remove dates from an array having a same year, month and day with higher times?

array(7) { 
    [0]=> string(19) "2012-06-11 08:30:49" 
    [1]=> string(19) "2012-06-11 08:03:54" 
    [2]=> string(19) "2012-05-26 23:04:04" 
    [3]=> string(19) "2012-05-27 08:30:00" 
    [4]=> string(19) "2012-06-08 08:30:55" 
    [5]=> string(19) "2012-06-08 08:31:12" 
    [6]=> string(19) "2012-06-08 08:55:24"
}

Will remove array[0],array[5],array[6]

Output:

('2012-06-11 08:03:54',''2012-05-26 23:04:04','2012-05-27 08:30:00','2012-06-08 08:30:55')

OR

'2012-06-11 08:03:54'
'2012-05-26 23:04:04'
'2012-05-27 08:30:00'
'2012-06-08 08:30:55'

In other words, I only want the earliest date on distinct days.

Upvotes: 2

Views: 1214

Answers (4)

Baba
Baba

Reputation: 95121

You can try using usort

$array = array( 
    "2012-06-11 08:30:49" ,
    "2012-06-11 08:03:54" ,
    "2012-05-26 23:04:04" ,
    "2012-05-27 08:30:00" ,
    "2012-06-08 08:30:55" ,
    "2012-06-08 08:31:12" ,
    "2012-06-08 08:55:24"
);


usort($array, function ($a, $b) {
    $a = strtotime($a);
    $b = strtotime($b);
    return ($a == $b) ? 0 : (($a > $b) ? - 1 : 1);
});

$list = array();
foreach ( $array as $time ) {
    $day = date('Y-m-d', strtotime($time));
    if (! array_key_exists($day, $list))
        $list[$day] = $time;
}

var_dump($list);

Output

array
  '2012-06-11' => string '2012-06-11 08:30:49' (length=19)
  '2012-06-08' => string '2012-06-08 08:55:24' (length=19)
  '2012-05-27' => string '2012-05-27 08:30:00' (length=19)
  '2012-05-26' => string '2012-05-26 23:04:04' (length=19)

Upvotes: 1

bhovhannes
bhovhannes

Reputation: 5679

The one way is to loop through sorted array eliminating higher time values when the dates remain constant. Below is working code:

echo '<pre>';
$in = array(
    '2012-06-11 08:30:49',
    '2012-06-11 08:03:54',
    '2012-05-26 23:04:04',
    '2012-05-27 08:30:00',
    '2012-06-08 08:31:12',
    '2012-06-08 08:30:55',
    '2012-06-08 08:55:24',
);
var_dump($in);

$out = $in;
sort($out, SORT_STRING);
for($i=count($out)-2; $i>=0; --$i)
{
    list($d1, $t1) = explode(' ', $out[$i+1]);
    list($d2, $t2) = explode(' ', $out[$i]);
    if($d1 == $d2 && $t2 <= $t1) //same date and lower time
    {
        unset($out[$i+1]);
    }
}

var_dump($out);
echo '</pre>';

If the order of elements is not important, this approach will be fast enough, because it is using php's sort() function and the only time consuming thing which is done in code is looping through array, which takes O(n) time.

Also, if you don't need to preserve original array, you can replace $out with $in everywhere and drop the $out=$in line. That will improve memory usage, since additional array will not be created.

Upvotes: 1

deceze
deceze

Reputation: 522175

$filtered = array();
foreach ($array as $time) {
    $day = date('Y-m-d', strtotime($time));
    if (!isset($filtered[$day]) || strtotime($filtered[$day]) > strtotime($time)) {
        $filtered[$day] = $time;
    }
}

Upvotes: 1

Riz
Riz

Reputation: 10246

$array = array( 
    "2012-06-11 08:30:49" ,
    "2012-06-11 08:03:54" ,
    "2012-05-26 23:04:04" ,
    "2012-05-27 08:30:00" ,
    "2012-06-08 08:30:55" ,
    "2012-06-08 08:31:12" ,
    "2012-06-08 08:55:24"
);

$new_array = array();
foreach($array as $item){
    $item_array = explode(" ", $item);
    $date = $item_array[0];
    $time = $item_array[1];
    if(!isset($new_array[$date]) || $time < $new_array[$date])
        $new_array[$date] = $time;
}

$final = array();

foreach($new_array as $key => $value){
    $final[] = $key . ' ' . $value;
}

print_r($final);

Upvotes: 1

Related Questions