0

I would like to search something in array of objects and remove the array position. For example, follow the array:
$audits = [{"old_values":[],"new_values":[],"event":"updated","auditable_id":"440","auditable_type":"App\\Models\\User","user_id":"433","user_type":"App\\Models\\User","url":"http:\/\/protocolo-online2\/logout?","ip_address":"127.0.0.1","user_agent":"Mozilla\/5.0 (X11; Linux x86_64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/102.0.0.0 Safari\/537.36","tags":"","created_at":"2023-02-01 09:55:00","login":"mailson.suporte"},{"old_values":{"ultimo_login":"2023-02-01 09:32:16"},"new_values":{"ultimo_login":"2023-02-01 09:55:10"},"event":"updated","auditable_id":"440","auditable_type":"App\\Models\\User","user_id":"440","user_type":"App\\Models\\User","url":"http:\/\/protocolo-online2\/login?","ip_address":"127.0.0.1","user_agent":"Mozilla\/5.0 (X11; Linux x86_64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/102.0.0.0 Safari\/537.36","tags":"","created_at":"2023-02-01 09:55:10","login":"mailson.suporte"}]

I tried to do this code:

if (($k = array_search(440, array_column(json_decode($audits, true), 'user_id'))) !== false) {
     unset($audits[$k]);
}

But this way is not working! I can do using foreach, this way:

foreach ($audits as $index => $audit) {
        if($audit->user_id == 440){
            unset($audits[$index]);
        }
 }

However if the array is start to grow up, I think that foreach is not a good method for this case.
Someone can help me?

  • 1
    The way your data is structured here, you have no choice but to iterate through the list one record at a time. So, yes it will get slower as the list grows. It looks like this array is the result of a database query, your best bet is going to be making the array as small as possible, like by filtering with `WHERE user_id = 440` on the query that generates the array. (Or `WHERE user_id != 440` if you want to exclude that user.) – Alex Howansky Feb 03 '23 at 15:21
  • You said: if the array [starts] to grow up, **I think** that foreach is not a good method - it depends on how much data you are processing. I think If just for cases where the number of data items is less than a few thousands then there is no much difference. – Ken Lee Feb 03 '23 at 15:24
  • I am getting these values from csv file. Before I was using the database, however I need to save in files now! – Rodrigo Franco Feb 03 '23 at 15:24
  • 1
    If you're getting the values from a CSV file then you _already_ have to read the whole file, so it doesn't matter. Your only (slightly improved) option would be to iterate over the file one row at a time with fgetcsv(), and then just skip importing the line if it matches your condition. – Alex Howansky Feb 03 '23 at 15:27
  • I don't see a [mcve] here. – mickmackusa Feb 04 '23 at 03:28

1 Answers1

0

I've had to write the array in php to make it work. But I think this example might be helpful.

This should return only the rows without the auditable_id's value to be equal to 440.

 $audits = [
    [
        "old_values" => [],
        "new_values" => [],
        "event" => "updated",
        "auditable_id" => "450",
        "auditable_type" => "App\\Models\\User",
        "user_id" => "433",
        "user_type" => "App\\Models\\User",
        "url" => "http://protocolo-online2/logout?",
        "ip_address" => "127.0.0.1",
        "user_agent" => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36",
        "tags" => "",
        "created_at" => "2023-02-01 09:55:00",
        "login" => "mailson.suporte"
    ],
    [
        "old_values" => [
            "ultimo_login" => "2023-02-01 09:32:16"
        ],
        "new_values" => [
            "ultimo_login" => "2023-02-01 09:55:10"
        ],
        "event" => "updated",
        "auditable_id" => "440",
        "auditable_type" => "App\\Models\\User",
        "user_id" => "440",
        "user_type" => "App\\Models\\User",
        "url" => "http://protocolo-online2/login?",
        "ip_address" => "127.0.0.1",
        "user_agent" => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36",
        "tags" => "",
        "created_at" => "2023-02-01 09:55:10",
        "login" => "mailson.suporte"
    ]
];

$audits = array_filter($audits, function ($audit) {
    return $audit['auditable_id'] != '440';
});
Edmon Belchev
  • 337
  • 2
  • 8
  • 2
    array_filter() is still O(N), it's no different than foreach(). – Alex Howansky Feb 03 '23 at 15:41
  • @AlexHowansky array_filter might be faster than foreach in some conditions. For this example it should be more optimized than foreach loop. But I should add that foreach might be way faster in bigger data. – Edmon Belchev Feb 03 '23 at 15:52
  • Cool man, but how to put two parameters inside the function, for example: ```$audits = array_filter($audits, function ($audit, $data) { return $audit['auditable_id'] != $data['auditable_id']; }); ``` – Rodrigo Franco Feb 03 '23 at 18:17
  • @Rod this new requirement is not mentioned in your question. Please do not add requirements upon receiving advice. – mickmackusa Feb 04 '23 at 03:26