如果键名不存在,array_column会返回什么?

问题描述:

According to https://wiki.php.net/rfc/array_column array_column is slated to be added to PHP soon. But I having trouble understanding the RFC. What will be returned if a named key doesn't exist?

Example:

$arr = array(
    array(
        'firstname' => 'Bob',
        'lastname'  => 'Tomato'
    ),
    array(
        'firstname' => 'Larry',
        'lastname'  => 'Cucumber'
    )
);

$middlenames = array_column($arr, 'middlename');

Introduction

For you to understand the RFC you need to understand the problem first and the reason it was introduced.

Your Array

$arr = array(
        array(
                'firstname' => 'Bob',    <--
                'lastname' => 'Tomato'     |    <--
        ),                                 |      |
        array(                             |      |
                'firstname' => 'Larry',  <--      |
                'lastname' => 'Cucumber'        <-|
        )
);

Getting Column

To get Bob & Larry or Tomato and Cucumber you have use more than one line of code examples are :

$colums = array();
foreach ( array_map(null, $arr[0], $arr[1]) as $value ) {
    $colums[] = $value;
}
print_r($colums);

Output

Array
(
    [0] => Array
        (
            [0] => Bob
            [1] => Larry
        )

    [1] => Array
        (
            [0] => Tomato
            [1] => Cucumber
        )

)

Dynamic Version

The code above would only work if you know number of elements another creative way would be

$colums = array();
array_unshift($arr, null);
foreach (call_user_func_array("array_map", $arr) as $value ) {
    $colums[] = $value;
}

Live Test

Or Better Sill use MultipleIterator

$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL);
foreach ( $arr as $v ) {
    $mi->attachIterator(new ArrayIterator($v));
}

$colums = array();
foreach ( $mi as $v ) {
    $colums[] = $v;
}
print_r($colums);

Live Test

Key Name

If you need to get the key name here is another method

$colums = array_reduce($arr, function ($a, $b) {
    foreach ( $b as $k => $v ) {
        $a[$k][] = $v;
    }
    return $a;
});

Live Test

Back to array_column

array_column intends simply the process and getting all columns with first name would be as simple as the following:

 print_r(array_column($arr,"lastname"));
                               ^
                               |
                               +--- This get value with key "lastname"

Live Test

More Complex Senerio

Imagine you want your array to have this output

Array
(
    [Bob] => Tomato
    [Larry] => Cucumber
)

Use Old methods you can have

$colums = array();
array_unshift($arr, null);
foreach (call_user_func_array("array_map", $arr) as $value ) {
    $key = array_shift($value);
    $colums[$key] = current($value);
}
print_r($colums);

Live Test

Now you can see i had to use array_shift and current to get first 2 element .. as your array grows this can become complex but array_column would simplify this

print_r(array_column($arr,"lastname","firstname"));
                              ^           ^
                              |           |
                             Value       Key    (I wonder why position is backwards)

Output

Array
(
    [Bob] => Tomato
    [Larry] => Cucumber
)

Finally Back to your Question

What will be returned if a named key doesn't exist?

Empty array ... From your example

 print_r(array_column($arr,"middlename"));
                                ^
                                |
                        it would try to check if any of your array has key middle man

It returns

Array        <------- Otherwise returns empty array 
(
)

Conclusion

I used so may different examples using loop , array_map , array_reduce and MultipleIterator to explain what array_column is trying to achieve.

As you can see array_column is much more simplified but i would advice you play with the examples in the RFC a little and this would allow you understand it better if you still don't understand it, PHP is a flexible language you can always implement your own version

As per: https://wiki.php.net/rfc/array_column

When a corresponding indexKey cannot be found, the value will be keyed with an integer, starting from zero.

Example used in RFC:

$mismatchedColumns = array(
   array(
       'a' => 'foo',
       'b' => 'bar',
       'e' => 'baz'
   ),
   array(
       'a' => 'qux',
       'c' => 'quux',
       'd' => 'corge'
   ),
   array(
       'a' => 'grault',
       'b' => 'garply',
       'e' => 'waldo'
   ),
);

$foo = array_column($mismatchedColumns, 'a', 'b');

Results in $foo equal to:

Array
(
   [bar] => foo
   [0] => qux
   [garply] => grault
)

Essentially, the value at a becomes the new array value, and b becomes the key. When the original array does not contain the key b, it creates a 0 index and uses that instead. If there were multiple keys that did not exist, they would be incremental from 0.

Looking into their examples a little further, it hints that when you are unable to match a value in the the original array, you won't get an array element at all. This means if you were looking for a single value in an array and it didn't exist, it would return an empty array.


P.S. I've obviously never used this function, so most of this is interpretation of the RFC.


On a side note, this function was accepted for inclusion in PHP and was originally proposed by Ben Ramsey with a final result from voting of 38 in favor and 6 against. The mailing list discussion can be viewed here: http://grokbase.com/t/php/php-internals/126nxxa80p/draft-rfc-array-column-function. See also https://github.com/php/php-src/pull/257