Разрезание многомерного массива PHP по одному из его элементов

StackOverflow https://stackoverflow.com/questions/163336

  •  03-07-2019
  •  | 
  •  

Вопрос

Скажем, например, что вы только что запросили базу данных и получили этот двумерный массив.

$results = array(
    array('id' => 1, 'name' => 'red'  , 'spin' =>  1),
    array('id' => 2, 'name' => 'green', 'spin' => -1),
    array('id' => 3, 'name' => 'blue' , 'spin' => .5)
);

Я часто нахожу, что пишу такие циклы.

foreach($results as $result)
    $names[] = $result['name'];

Мои вопросы: существует ли способ получить этот массив $ names без использования цикла? Использование функций обратного вызова считается как использование цикла.

Вот более общий пример получения каждого поля.

foreach($results as $result)
    foreach($result as $key => $value)
        $fields[$key][] = $value;
Это было полезно?

Решение

С 20 июня в PHP-5.5 появилась новая функция array_column

Например:

$records = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe'
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith'
    ),
    array(
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Jones'
    ),
    array(
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe'
    )
);


$firstNames = array_column($records, 'first_name');
print_r($firstNames);

Вернется

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)

В приведенной выше ссылке есть еще больше примеров.

Другие советы

Я проголосовал за ответ @ Devon, потому что на самом деле нет способа сделать то, что вы просите, с помощью встроенной функции. Лучшее, что вы можете сделать, это написать свое собственное:

function array_column($array, $column)
{
    $ret = array();
    foreach ($array as $row) $ret[] = $row[$column];
    return $ret;
}

Начиная с PHP 5.3, вы можете использовать этот симпатичный вызов с лямбда-функцией:

$names = array_map(function ($v){ return $v['name']; }, $results);

Это вернет массив, разрезанный по размеру 'name'.

Проще говоря, нет.

Вам нужно будет использовать цикл или функцию обратного вызова, например, array_walk .

Я провел дополнительные исследования по этому вопросу и обнаружил, что и ruby, и прототип имеют функцию, которая делает это, называемую array_pluck , 2 . Интересно, что у array_map есть второе использование, которое позволяет вам делать то, что я хочу сделать здесь. Я также нашел PHP класс , который кто-то пишет для эмуляции прототипов манипулирования массивами.

Я собираюсь еще немного покопаться, и если я не найду ничего другого, я поработаю над патчем для отправки в список рассылки internals@lists.php.net и посмотрю, добавят ли они array_pluck.

Для тех из вас, кто не может перейти на PHP5.5 прямо сейчас и нуждается в этой функции, вот реализация array_column .

function array_column($array, $column){
    $a2 = array();
    array_map(function ($a1) use ($column, &$a2){
        array_push($a2, $a1[$column]);
    }, $array);
    return $a2;
}

Если вы используете версию PHP до 5.5 и array_column () , вы можете использовать официальную замену в простом PHP:

https://github.com/ramsey/array_column

Я думаю, что это будет делать то, что вы хотите

array_uintersect_uassoc

Вы должны сделать что-то подобное

$results = array(
    array('id' => 1, 'name' => 'red'  , 'spin' =>  1),
    array('id' => 2, 'name' => 'green', 'spin' => -1),
    array('id' => 3, 'name' => 'blue' , 'spin' => .5)
);
$name = array_uintersect_uassoc( $results, array('name' => 'value')  , 0, "cmpKey");
print_r($name);

//////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////
function cmpKey($key1, $key2) {
  if ($key1 == $key2) {
    return 0;
  } else {
    return -1;
  }
}

Однако у меня нет доступа к PHP5, поэтому я не проверял это.

Вы можете сделать:

$tmp = array_flip($names);
$names = array_keys($tmp);

Это быстрая альтернатива функции array_column ()

if(!function_exists('array_column')) {
    function array_column($element_name) {
        $ele =   array_map(function($element) {
            return $element[$element_name];
        }, $a);
        return  $ele;
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top