Подтвердить что ты не робот

В PHP есть функция, которая возвращает массив, состоящий из значения ключа из массива ассоциативных массивов?

Я уверен, что этот вопрос был задан раньше, мои извинения за то, что он не нашел его первым.

Исходный массив:

[0] => Array
    (
        [categoryId] => 1
        [eventId] => 2
        [eventName] => 3
        [vendorName] => 4
    )

[1] => Array
    (
        [categoryId] => 5
        [eventId] => 6
        [eventName] => 7
        [vendorName] => 8
    )

[2] => Array
    (
        [categoryId] => 9
        [eventId] => 10
        [eventName] => 11
        [vendorName] => 12
    )

Я надеялся на результат из: print_r (get_values_from_a_key_in_arrays ('categoryId', $array));

[0] => 1
[1] => 5
[2] => 9

Я просто ищу что-то более чистое, чем писать свою собственную функцию foreach. Если foreach является ответом, у меня уже есть это место.

Изменить: Я не хочу использовать жестко закодированный ключ, я просто показывал пример вызова решения. Благодарю! ^ _ ^

Quick Grab Solution для PHP 5.3:

private function pluck($key, $data) {
    return array_reduce($data, function($result, $array) use($key) {
        isset($array[$key]) && $result[] = $array[$key];
        return $result;
    }, array());
}
4b9b3361

Ответ 1

Итак, классная вещь о более высокого порядка коллекция/функции итератора, такие как pluck, filter, each, map, и друзья в том, что их можно смешивать и сопоставлять, чтобы составить более сложный набор операций.

Большинство языков предоставляют эти типы функций (ищите пакеты, такие как сбор, итератор или перечисление/перечисляемые)... некоторые предоставляют больше функций, чем другие, и вы обычно увидите, что функции называются по-разному на разных языках (т.е. collect = = map, уменьшите == fold). Если функция не существует на вашем языке, вы можете создать ее из тех, которые существуют.

Что касается вашего тестового примера... мы можем использовать array_reduce для реализации pluck. Первая версия, которую я написал, основывалась на array_map; однако я согласен с @salathe, что array_reduce является более кратким для этого задача; array_map - это вариант OK, но в конце концов вам нужно больше работать. array_reduce может выглядеть немного странно, но если обратный вызов аккуратно организован, все хорошо.

Менее наивный pluck также проверит, может ли он "вызывать" (функцию/метод) на итерированном значении. В наивной реализации ниже мы предполагаем, что структура является хешем (ассоциативный массив).

Это позволит настроить тестовые данные (светильники):

<?php

$data[] = array('categoryId' => 1,    'eventId' => 2,  'eventName' => 3,  'vendorName' => 4);
$data[] = array('categoryId' => 5,    'eventId' => 6,  'eventName' => 7,  'vendorName' => 8);
$data[] = array('categoryId' => 9,    'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array(/* no categoryId */   'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => false,'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => 0.0,  'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);

Выберите версию, которую вы предпочитаете

$preferredPluck = 'pluck_array_reduce'; // or pluck_array_map

"pluck" для PHP 5.3+: array_reduce обеспечивает краткую реализацию, хотя и не так просто рассуждать о версии массива:

function pluck_array_reduce($key, $data) {
  return array_reduce($data, function($result, $array) use($key){
    isset($array[$key]) &&
      $result[] = $array[$key];

    return $result;
  }, array());
}

"pluck" для PHP 5.3+: array_map не идеален для этого, поэтому нам нужно больше проверять (и он по-прежнему не учитывает многие потенциальные случаи):

function pluck_array_map($key, $data) {
  $map = array_map(function($array) use($key){
    return isset($array[$key]) ? $array[$key] : null;
  }, $data);

  // is_scalar isn't perfect; to make this right for you, you may have to adjust
  return array_filter($map, 'is_scalar');
}

"выщипывать" для устаревшего PHP < 5.3

Мы могли бы использовать устаревшее create_function; однако, это плохая форма, не рекомендуется, а также совсем не изящная, поэтому я решил не показывать ее.

function pluck_compat($key, $data) {
  $map = array();
  foreach ($data as $array) {
    if (array_key_exists($key, $array)) {
      $map[] = $array[$key];
    }
  }
  unset($array);

  return $map;
}

Здесь мы выбираем версию "pluck" для вызова на основе версии PHP, которую мы запускаем. Если вы запустите весь script, вы должны получить правильный ответ независимо от того, в какой версии вы находитесь.

$actual   = version_compare(PHP_VERSION, '5.3.0', '>=')
          ? $preferredPluck('categoryId', $data)
          : pluck_compat('categoryId', $data);
$expected = array(1, 5, 9, false, 0.0);
$variance = count(array_diff($expected, $actual));

var_dump($expected, $actual);
echo PHP_EOL;
echo 'variance: ', $variance, PHP_EOL;

print @assert($variance)
    ? 'Assertion Failed'
    : 'Assertion Passed';

Обратите внимание, что окончание '? > ' отсутствует. Это потому, что это не нужно. Более хорошее может состоять в том, чтобы оставить его, а не держать его вокруг.

FWIW, похоже, что это добавляется к PHP 5.5 как array_column.

Ответ 2

Картирование - это то, что вам нужно:

$input = array(
    array(
        'categoryId' => 1,
        'eventId' => 2,
        'eventName' => 3,
        'vendorName' => 4,
    ),
    array(
        'categoryId' => 5,
        'eventId' => 6,
        'eventName' => 7,
        'vendorName' => 8,
    ),
    array(
        'categoryId' => 9,
        'eventId' => 10,
        'eventName' => 11,
        'vendorName' => 12,
    ),
);

$result = array_map(function($val){
    return $val['categoryId'];
}, $input);

Или создав нужную функцию:

function get_values_from_a_key_in_arrays($key, $input){
    return array_map(function($val) use ($key) {
        return $val[$key];
    }, $input);
};

а затем используя его:

$result = get_values_from_a_key_in_arrays('categoryId', $array);

Он будет работать в PHP >= 5.3, где разрешены анонимные обратные вызовы. Для более ранних версий вам нужно будет определить обратный вызов раньше и передать его имя вместо анонимной функции.

Ответ 3

Для этого нет встроенной функции, но обычно она называется pluck".

Ответ 4

<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

function get_a($v) {
        return $v['a'];
}

var_dump(array_map('get_a', $a));

Вы можете использовать функцию create_function или анонимную функцию (PHP 5.3 > =)

<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

var_dump(array_map(create_function('$v', 'return $v["a"];'), $a));

Я бы написал функцию обратного вызова, как описано выше, а затем применил ее с помощью массива array_map.

Ответ 5

Нет встроенной функции. Но можно легко сделать с помощью array_map().

$array = array(
    array(
        "categoryID"   => 1,
        "CategoryName" => 2,
        "EventName"    => 3,
        "VendorName"   => 4
    ),
    array(
        "categoryID"   => 5,
        "CategoryName" => 6,
        "EventName"    => 7,
        "VendorName"   => 8
    ),
    array(
        "categoryID"   => 9,
        "CategoryName" => 10,
        "EventName"    => 11,
        "VendorName"   => 12
    )
);

$newArray = array_map(function($el) {
    return $el["categoryID"];
}, $array);

var_dump($newArray);

Ответ 6

Где lisp, когда вам это нужно? На самом деле в php тоже довольно легко управлять. Просто используйте функцию array_map, как показано ниже.

# bunch o data
$data = array();
$data[0] = array("id" => 100, "name" => 'ted');
$data[1] = array("id" => 200, "name" => 'mac');
$data[2] = array("id" => 204, "name" => 'bub');

# what you want to do to each bit of it
function pick($n) { return($n['id']); }
# what you get after you do that
$map = array_map("pick", $data);
# see for yourself
print_r($map);

Ответ 7

Начиная с PHP 5.5, используйте array_column:

$events = [
    [ 'categoryId' => 1, 'eventId' =>  2, 'eventName' =>  3, 'vendorName' =>  4 ],
    [ 'categoryId' => 5, 'eventId' =>  6, 'eventName' =>  7, 'vendorName' =>  8 ],
    [ 'categoryId' => 9, 'eventId' => 10, 'eventName' => 11, 'vendorName' => 12 ],
];

print_r(array_column($events, 'categoryId'));

Посмотрите онлайн в 3v4l.

Для версий до 5.5 вы можете использовать polyfill.

Ответ 8

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

Ответ Tadeck лучше.