0

I have a multidimensional array in PHP where I need to remove one array based on the value of an item in one of the arrays:

Example Array

array(
   "0"=>array("0"=>"joe", "1"=>"2018-07-18 09:00:00"),
   "1"=>array("0"=>"tom", "1"=>"2018-07-17 09:00:00"),
   "2"=>array("0"=>"joe", "1"=>"2018-07-14 09:00:00")
)

I know that I want to remove the array that contains joe in key 0, but I only want to remove the array that contains joe with the most current date in key1. The following output is what I'm trying to accomplish:

array(
   "0"=>array("0"=>"tom", "1"=>"2018-07-17 09:00:00"),
   "1"=>array("0"=>"joe", "1"=>"2018-07-14 09:00:00")
) 

Is there a simple way to do this in PHP aside from looping through each array?

MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77
Austin
  • 1,619
  • 7
  • 25
  • 51
  • Possible duplicate of [Delete element from multidimensional-array based on value](https://stackoverflow.com/questions/4466159/delete-element-from-multidimensional-array-based-on-value) – ficuscr Jul 18 '18 at 19:08
  • No. Well a callback I guess... array_filter? Still "looping" though. – ficuscr Jul 18 '18 at 19:10
  • 1
    Is the most current always at the top? – Andreas Jul 18 '18 at 19:13
  • the most current is not necessarily at the top all the time – Austin Jul 18 '18 at 19:14
  • @ficuscr this is not a duplicate post as it requires the date to be taken into account and only one array is to be removed, not every array that contains `joe` – Austin Jul 18 '18 at 19:16
  • 2
    Your question is very confusing as it is written. Would it be right to summarize your question as "Keep the oldest Joe"? What do you expect to happen if there are 3 Joes or two Joes with the same timestamp? What happens if there were 2 Toms and 3 Joes? – MonkeyZeus Jul 18 '18 at 19:26

2 Answers2

3

Here is a non looping method that uses array_intersect and array_column to find the "Joe's" and then deletes the maximum array_key since I first sort the array on dates.

usort($arr, function($a, $b) {
    return $a[1] <=> $b[1];
}); // This returns the array sorted by date

// Array_column grabs all the names in the array to a single array.
// Array_intersect matches it to the name "Joe" and returns the names and keys of "Joe"
$joes = array_intersect(array_column($arr, 0), ["joe"]);

// Array_keys grabs the keys from the array as values
// Max finds the maximum value (key)
$current = max(array_keys($joes));
unset($arr[$current]);

var_dump($arr);

https://3v4l.org/mah6K

Edit forgot to add the array_values() if you want to reset the keys in the array.

Just add $arr = array_values($arr); after the unset.

Andreas
  • 23,610
  • 6
  • 30
  • 62
  • Nice. That `array_column` has been a great addition. – ficuscr Jul 18 '18 at 19:32
  • @ficuscr Agree, I use array_column on pretty much every answer I write here. Though, I think in the background array_column does some looping. Not sure though. – Andreas Jul 18 '18 at 19:34
1

I would go about it like this:

<?php
 $foo = array(
   "0"=>array("0"=>"joe", "1"=>"2018-07-18 09:00:00"),
   "1"=>array("0"=>"tom", "1"=>"2018-07-17 09:00:00"),
   "2"=>array("0"=>"joe", "1"=>"2018-07-14 09:00:00")
);


$tmp = [];  
foreach($foo as $k => $v) {
    if ($v[0] === 'joe') {
        $tmp[$v[1]] = $k;
    }
}
if (!empty($tmp)) {
    sort($tmp);  //think that is sane with date format?
    unset($foo[reset($tmp)]);
}

var_dump($foo);

Not sure if you don't want to loop on principal or what... I tend to go for readability. Find all occurrences of joe. Sort on date. Remove the most recent by key.

ficuscr
  • 6,975
  • 2
  • 32
  • 52