1

I have a function that work good in php 7 but in php 8.0.11 has warning

$orders->result = array_map('reset', $orders->result);

E_WARNING: reset(): Argument #1 ($array) must be passed by reference, value given in

Of course, I can use this code instead that but maybe slower than array_map

foreach ($orders->result as $item)
       $result[$item[0]['order_id']] = $item[0];

Edit: before foreach or array_map the output like this

    Array
(
    [0] => Array
        (
           [order_id] => 41111909
           [shop_id] => 34277
           [user_id] => 42363
           [status_id] => 4
         )
)

after use foreach output like this

Array
(
    [41111909] => Array
        (
           [order_id] => 41111909
           [shop_id] => 34277
           [user_id] => 42363
           [status_id] => 4
         )
)
            

How to solve it ?

6
  • stackoverflow.com/questions/65947307/… maybe that will help Commented Oct 19, 2021 at 15:30
  • "Of course, I can use this code instead that but maybe slower than array_map" I think this is false. Commented Oct 19, 2021 at 15:32
  • Your alternative code doesn't seem to actually do the same thing - it looks up 'order_id' on each item. It would be equivalent to array_map(fn($item) => $item[0]['order_id'], $orders->result). I also agree with AymDev that it's not particularly likely to be slow. Commented Oct 19, 2021 at 15:36
  • Did you give up? Commented Oct 20, 2021 at 2:55
  • 1
    Your latest edit is even more confusing: it's not the result that either of the versions of the code you showed would give. I would strongly recommend stepping back and creating a minimal reproducible example - some actual example input and code that you can run on its own. Commented Oct 20, 2021 at 12:53

2 Answers 2

5

The simplest replacement is to make an arrow function (single-expression closure) to get the element for you.

If the arrays are plain lists, so that you're always getting element 0, that's as simple as:

$orders->result = array_map(fn($item) => $item[0], $orders->result);

Another alternative in this case is array_column:

$orders->result = array_colum($orders->result, 0);

If you have other keys, you could use either reset or array_key_first in the callback instead:

$orders->result = array_map(fn($item) => $item[array_key_first($item)], $orders->result);

(I suspect array_key_first will be slightly more efficient, since it doesn't need to manipulate the internal array pointer.)

Sign up to request clarification or add additional context in comments.

Comments

1

It's not entirely clear what you're trying to do, but it seems like you are trying to get the first value from nested arrays. You should be able to use a function:

$orders->result = array_map(function($v) { return reset($v); }, $orders->result);

You may also try using current if it does what you need as it doesn't take a reference and the array pointer should already be reset by array_map:

$orders->result = array_map('current', $orders->result);

After the edit the code in question is not re-indexing the array as you show in the before and after. To do that is simple:

$orders->result = array_column($orders->result, null, 'order_id');

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.