Итак, самое интересное в высшем порядке функции коллекции/итератора, такие как выщипывать, фильтровать, каждый, map, и друзья в том, что их можно смешивать и сопоставлять, чтобы составить более сложный набор операций.
Большинство языков предоставляют эти типы функций (ищите такие пакеты, как collection, iterator или enumeration/enumerable)... некоторые предоставляют больше функций, чем другие, и вы обычно увидите, что функции названы по-разному в разных языках (например, collect == map, уменьшить == свернуть). Если функция не существует в вашем языке, вы можете создать ее из существующих.
Что касается вашего тестового случая... мы можем использовать array_reduce для реализации щипка. Первая опубликованная мной версия опиралась на array_map
; однако я согласен с @salathe, что array_reduce более лаконичен для этой задачи; array_map — хороший вариант, но в конечном итоге вам придется проделать больше работы. 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);
Выберите предпочтительную версию pluck
$preferredPluck = 'pluck_array_reduce'; // or pluck_array_map
"puck" для PHP 5.3+: array_reduce обеспечивает краткую реализацию, хотя и не такую простую для понимания, как версия array_map:
function pluck_array_reduce($key, $data) {
return array_reduce($data, function($result, $array) use($key){
isset($array[$key]) &&
$result[] = $array[$key];
return $result;
}, array());
}
"puck" для 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. Если вы запустите весь сценарий, вы должны получить правильный ответ независимо от того, какая у вас версия.
$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 как столбец_массива.
person
Wil Moore III
schedule
18.05.2012
plucking
и не является функцией PHP по умолчанию. Хотя вы можете легко написать его сами. - person Joost   schedule 19.05.2012plucking
. - person Moses   schedule 19.05.2012array_reduce()
— НЕПРАВИЛЬНАЯ функция. Он предназначен для уменьшения массива до одного значения. Это верно и для других языков. Вы должны переписать с помощьюarray_map()
илиarray_walk()
... что также упростит код. - person doublejosh   schedule 25.06.2016array_reduce
здесь все в порядке. Он сводит массив массивов к массиву значений. - person Michael   schedule 28.07.2016