rfc:array_change_keys

This is an old revision of the document!


PHP RFC: array_change_keys()

Introduction

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:

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

This approach requires no less than 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:

<?php
$newArray = array_combine(
    array_map(function ($value) {
        return 'someValue'; // Whatever custom logic is needed
    }, array_values($oldArray)),
    array_values($oldArray)
);

While this does work, it has some major drawbacks:

  • Requires no less than 4 function calls, each of which returns a new array.
  • The anonymous function only has access to the original key or the original value - not both.
  • The purpose of the code is not immediately obvious.

Proposal

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

array array_change_keys(array $originalArray, callable $callback)

This function takes two arguments:

  1. An array to re-key.
  2. A callable which returns a new key for each array element.

The new array returned by this function will contain the same values in the same order, but with potentially different keys.

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

Callable

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

  1. The element's original key (string or int)
  2. The element's original value (mixed)

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

Returning Invalid Types

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 one “wins”. For example:

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

Function Name

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

Other function 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

Faster Execution

Re-keying an array with array_change_keys() is faster than the two alternate approaches shown earlier:

Cleaner Code

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

Cons

Backward Incompatible Changes

None

Proposed PHP Version(s)

Next PHP 7.x release

RFC Impact

To SAPIs

This RFC should not impact the SAPI's.

To Existing Extensions

No existing extensions are affected.

To Opcache

Unknown

Open Issues

None

Future Scope

Returning __toString()able objects from the callback is not supported by this RFC. This matches the behavior of other functions like array_flip() and array_fill_keys(). If such functionality is desired, a separate RFC could be created to add this functionality to all similar functions.

Proposed Voting Choices

This RFC will require a 2/3 majority (see voting).

Patches and Tests

A proposed implementation is provided with this RFC: https://github.com/php/php-src/pull/1925

Several tests are also included.

References

Links to external references, discussions or RFCs

rfc/array_change_keys.1464527677.txt.gz · Last modified: 2017/09/22 13:28 (external edit)