Php change key from array

Is it a good idea to modify the array keys in foreach

I always use a temp array to achieve that, but I had a memory problem when working on a project that had some big arrays. Of course the best solution is to increase the memory but, but i was just wondering is it so bad to just do it like:

foreach($arrayIWantToModify as $key => $value) < if(($value % 2) == 0) < $arrayIWantToModify['odd_' . $key] = $value; unset($arrayIWantToModify[$key]); >> 

It seems to work but I always saw it as a bad practice because you are changing an array you are iterating.

3 Answers 3

I would agree that this is not a good idea. Even if the language you’re using defines what should happen in this situation (I don’t know if PHP does; that’s a question for StackOverflow) most people who see code like this would still have to look up whether or not it’s defined behavior before they could have any confidence in it.

If the list of desired modifications is typically much smaller than the array being modified, I would always prefer using a temporary array to contain the desired modifications until the iterating is complete, just like your first example. If you’re running out of memory doing that, that tells me you’re modifying such a huge portion of the array that you’d be better off with a map operation (I believe PHP calls it array_map ) that’s designed to efficiently modify all elements without any risk of processing an element more or less than one time.

In PHP the foreach loop creates a temporary variable storing the initial array passed. you can pass $value by reference using &$value. In the two examples below the loops remove the next element in the array.

Since it is a temporary variable changes to the original have no effect on the foreach loop.

Let’s use a slightly different take on the problem. You describe what you do as:

Some times I need to modify an array key

When we look at it like this, we have the problem of doing everything in the same loop. Can we look at it differently? Maybe say:

Some times I need to find a set of keys, and then I need to modify those keys in the array

Now we can see two separate tasks to complete, which means we can break them apart. The code to accomplish this might look something like:

$oddKeys = array(); // Task 1: Find a set of keys foreach($arrayIWantToModify as $key => $value) < if($value % 2 == 0) < $oddKeys[] = $key; >> // Task 2: Modify those keys foreach($oddKeys as $key)

We have less memory usage* than the temporary array as we are only storing the keys that need to change, not an entire duplicate array. The code is also clearer than the alternative as there is no question about the behavior here. Since we’ve broken the behavior apart, we can now even extract it and reuse it elsewhere (for example by extracting a function that returns an array of keys where the values meet certain criteria).

Читайте также:  Html table caption styling

* If the number of keys that need to change is the same or nearly the same as the total number of keys, the memory usage gains may not be as large. You would need to test whether you are still running into memory limitations, and possibly come up with a different strategy (say, swap all the keys, then reverse the action on the reverse condition).

Источник

PHP RFC: array_change_keys()

This RFC proposes a new core function to simplify the process of changing an array’s keys (“re-keying”).

The Problem

PHP only has one existing function to change an array’s keys: array_change_key_case() . Unfortunately this can only transform keys to upper- or lower-case.

Because this function doesn’t allow developers to specify their own custom logic to transform keys to something else, one must typically resort to using a foreach loop to build a new array:

 $newArray = []; foreach ($oldArray as $key => $value) { $newKey = 'someValue'; // Whatever custom logic is needed $newArray[$newKey] = $value; }

This approach requires 4 lines of code. Furthermore, this logic cannot be wrapped as a parameter to some other function.

That latter issue can solved by composing several existing functions like so:

 $newArray = array_combine( array_map( function ($key, $value) { return 'someValue'; // Whatever custom logic is needed }, array_keys($oldArray), $oldArray ), $oldArray );

While this does work, it has some major drawbacks:

If you want to re-key an iterator’s results, you cannot do so inline — a temporary variable would be needed to convert the iterator to array first.

Proposal

This RFC proposes the creation of a new core function array_change_keys() :

$newArray = array_change_keys($originalArray, function ($key, $value) { return 'someValue'; // Whatever custom logic is needed });
array array_change_keys(array $originalArray, callable $callback)

This function takes two arguments:

(This parameter order is consistent with all other array functions except for array_map() , which is a special case due to its variadic nature.)

A new array will be returned from this function, containing the same values in the same order but with potentially different keys. Some values may not be included if an invalid or duplicate key is returned by the callback. This behavior is identical to array_flip() and is documented in the “Callback” subsections further below.

Callback

Two parameters will be passed to the callable for each element in the array:

The callable must return a string or int to be used as the new key.

Returning Invalid Types

The callable must return a valid key. Returning any type besides string or int will result in the following warning:

Warning: array_change_keys(): New key should be either a string or an integer

Additionally, the current array item will not be added to the resulting array. PHP will still attempt to process all subsequent elements.

This matches the behavior of calling array_flip on an array containing types other than string or int .

Returning Duplicate Keys

If the callable returns the same key for multiple values, the last occurrence “wins” and all prior values will be lost. For example:

 var_dump(array_change_keys([1, 2, 3], function(){ return 'foo'; })); // array(1) // ["foo"]=> // int(3) // >

This behavior also matches array_flip() .

Function Name

PHP already has an array_change_key_case() function, so sharing a common root name ( array_change_key ) seems like a logical choice.

Other functions which deal with multiple keys (like array_keys and array_fill_keys ) are pluralized, so we’re using that same convention here.

Discussion

This section will be updated with any additional pros/cons that arise during the discussion period.

Pros

Provides Common General-Purpose Functionality

PHP already has an array_change_key_case function, which is an incredibly specific implementation that isn’t useful in the majority of cases where an array needs to be re-keyed. By providing a general-purpose function for a common problem we prevent the need for other array_change_key_* variants in the future.

Usefulness

Needing to re-key array is a common task for some PHP developers, especially those needing their array to work like a dictionary.

Cleaner Code

Using this function makes it immediately obvious to other developers that an array is being re-keyed.

Matches Existing Behavior

The “edge cases” mentioned above (returning invalid types or duplicate keys) matches existing behavior in PHP that developers already understand and expect. No new edge cases or quirks are being introduced with this RFC .

Faster Execution Than array_combine()

Re-keying an array with array_change_keys() is faster than the array_combine approach:

Works With Functional Code

This function can be nested inside of other method calls for function composition. The same is not possible for the foreach approach (without requiring the creation of a separate method to encapsulate that functionality).

Cons

Slower Than foreach

As noted in the benchmarks above, the foreach loop approach is faster than array_change_keys in most (but not all) cases.

Does Not Support Traversable

Like the other array_ functions, this one also doesn’t support iterators, which may be seen as a step backwards.

Easily Implemented In User Land

This function can be implemented in user land using one of the alternative approaches shown above. There’s a general feeling among some developers that “what can be implemented in userland shouldn’t be in core”.

Источник

Php change key from array

Здесь немного нужно сказать о теории.

Нет такого .. простого способа или функции, которая возьмет и заменит ключ, именно ключ, имя ключа на другое. Просто нет и все.

Поэтому требуется несколько телодвижений.

Алгоритм замены ключа, имени ключа

(далее просто «замена ключа».)

Нам потребуется получить значение ячейки старого ключа, который мы хотим изменить, переименовать. Присвоить новому ключу значение старого ключа.
После того, как новый ключ создан со значением старого ключа . У нас получиться, что есть две ячейки с одинаковыми значениями, но два ключа, «старый ключ» и «новый ключ».

Следующим шагом — мы спокойно можем удалить старый ключ.

Пример замены ключа в массиве:

Для иллюстрации нам понадобится массив:

Выведем прямо здесь с помощью print_r:

Array 

(

[0] => Ячейка 1 [1] => Ячейка 2 [2] => Ячейка 3 [3] => Ячейка 4

)

Предположим, что мы хотим заменить ключ второй ячейки, ключ №1.

1). Получаем значение ключа в новую ячейку:

Опять выведем, что у нас получилось — print_r($array_example);

Array 

(

[0] => Ячейка 1 [1] => Ячейка 2 [2] => Ячейка 3 [3] => Ячейка 4 [4] => Ячейка 2

)

Для удаления строго ключа нам потребуется функция unset:

Результат замены ключа в массиве.

Array 

(

[0] => Ячейка 1 [2] => Ячейка 3 [3] => Ячейка 4 [4] => Ячейка 2

)

Вывод о замене ключа:

При такой замене имени ключа, нарушается нумерация ключей. Теперь нам нужно(если нужно) восстановить нумерацию ключей

Array 

(

[0] => Ячейка 1 [1] => Ячейка 3 [2] => Ячейка 4 [3] => Ячейка 2

)

Замена ключа без изменения положения ключа.

Но, что, если вам требуется сохранить положение ключа в массиве и заменить его имя — есть какие-то варианты?

Поскольку у меня на сайте есть множество данных хранимых в ассоциативных массивах, то и ключи периодически приходится заменять, но , чтобы место данного ключа не менялось!

Замена имени ключа в цикле.

Предположим, что у нас есть ассоциативный массив(приведем простой пример такого массива):

Array 

(

[помидоры] => 15 [огурцы] => 12 [петрушка] => 22 [бананы] => 16

)

Замена ключа без изменения положения в массиве:

Предположим, что в выше приведенном массиве нам требуется изменить имя ключа номер 2(огурцы) на какое-то другое, без изменения положения в массиве, для этого вам понадоится:

Выше цикла создаем новый массив:

Для этого примера нам понадобится, цикл foreach

Внутри цикла создадим условие if и проверим, если ключ массива «огурцы»

То, создаем в цикле новый массив «$new_arr» с новым ключом «новые_огурцы» и значением старого ключа:

И далее. вернем в старый массив новый:

Соберем весь код замены ключа на новый:

foreach ($price as $key => $value)

Ну и далее. нам остается только вывести результат замены ключа в массиве, без изменения его положения:

Результат вывода замены ключа:

Array 

(

[помидоры] => 15 [новые_огурцы] => 12 [петрушка] => 22 [бананы] => 16

)

16.09.2022 13:37 Сергей Fortoo

unset ($price[$key]);
Убить старый ключ нужно когда переименование ключа происходит в первоначальном массиве, а в данном примере, Вы создаёте новый массив, поэтому unset ($price[$key]); не нужен.

16.09.2022 14:58 Марат Сергей Fortoo

Источник

Оцените статью