#php #multidimensional-array
#php #многомерный массив
Вопрос:
Я использую array_filter, чтобы сделать что-то вроде этого:
function endswithy($value) {
return (substr($value, -1) == 'y');
}
$people = array("Johnny", "Timmy", "Bobby", "Sam", "Tammy", "Danny", "Joe");
$withy = array_filter($people, "endswithy");
var_dump($withy);
НО с дополнительной опцией в filter, например
$people = array(
"Johnny"=>array("year"=>1989, "job"=>"prof"),
"Timmy"=>array("year"=>1989, "job"=>"std"),
"Bobby"=>array("year"=>1988),
"Sam"=>array("year"=>1983),
"Tammy"=>array("year"=>1985),
"Danny"=>array("year"=>1983),
"Joe"=>array("year"=>1989,"job"=>"prof"));
или
$people = array(
array("name"=>"Johnny","year"=>1989, "job"=>"prof"),
array("name"=>"Timmy","year"=>1989, "job"=>"std"),
array("name"=>"Bobby""year"=>1988),
array("name"=>"Sam","year"=>1983),
array("name"=>"Tammy","year"=>1985),
array("name"="Danny","year"=>1983),
array("name"="Joe","year"=>1989,"job"=>"prof"));
Как я могу получить только эти данные (заканчивающиеся на y
и year=1989
и job=prof
), могу ли я использовать array_filter?
или какая-либо встроенная функция для этого?
$people = array(
"Johnny"=>array("year"=>1989, "job"=>"prof")
);
или
$people = array(
array("name="Johnny","year"=>1989, "job"=>"prof")
);
Комментарии:
1. Можете ли вы использовать name в качестве значения внутреннего массива, а не ключа внешнего массива? Т.е.,
$people = array(array('name' => 'Johnny', 'year' => 1989, 'job' => 'prof'), ...)
2. Если вы можете это сделать, тогда нет проблем с использованием
array_filter()
. Вы получите массив в качестве аргумента функции обратного вызова (endswithy()
), так что вы можете проверить как имя, так и год. Если вам это нужно только один раз, вы также можете использоватьforeach
цикл для удаления ненужных элементов. Я привел примеры с обоимиarray_filter()
иforeach
в моем ответе ниже.
Ответ №1:
PHP 5.6 вводит необязательный флаг ARRAY_FILTER_USE_KEY
, который позволит это:
function endswithy($name) {
return (substr($name, -1) == 'y');
}
$people = array(
"Johnny"=>array("year"=>1989, "job"=>"prof"),
"Timmy"=>array("year"=>1989, "job"=>"std"),
"Bobby"=>array("year"=>1988),
"Sam"=>array("year"=>1983),
"Tammy"=>array("year"=>1985),
"Danny"=>array("year"=>1983),
"Joe"=>array("year"=>1989,"job"=>"prof")
);
$peopleEndingInY = array_filter($people, 'endswithy', ARRAY_FILTER_USE_KEY);
// Outputs: 5
var_dump(count($peopleEndingInY));
Если вам нужно сохранить и ключ и значение, другой флаг ARRAY_FILTER_USE_BOTH
сделает это, как показано в этом примере:
$ar = array(
'key1' => 'value1',
'key2' => 'value2'
);
//Note that this doens't actually filter anything since it doesn't return a bool.
$output = array_filter($ar, function($value, $key){
echo sprintf("%s => %sn", $key, $value);
}, ARRAY_FILTER_USE_BOTH);
Комментарии:
1. отличный ответ, который не требует от вас изменения структуры данных.
Ответ №2:
Либо используйте foreach
со структурой вашего текущего массива:
$people = array(
"Johnny" => array("year" => 1989, "job" => "prof"),
"Timmy" => array("year" => 1989, "job" => "std"),
"Bobby" => array("year" => 1988),
"Sam" => array("year" => 1983),
"Tammy" => array("year" => 1985),
"Danny" => array("year" => 1983),
"Joe" => array("year" => 1989, "job" => "prof"),
);
foreach ( $people as $name => $info ) {
if ( substr($name, -1) !== 'y' || $info['year'] != 1989 ) {
unset($people[$name]);
}
}
print_r($people);
// output:
Array
(
[Johnny] => Array
(
[year] => 1989
[job] => prof
)
[Timmy] => Array
(
[year] => 1989
[job] => std
)
)
Или преобразовать ваш массив так, чтобы name было значением внутреннего массива:
$people = array(
array('name' => 'Johnny', 'year' => 1989, 'job' => 'prof'),
array('name' => 'Timmy' , 'year' => 1989, 'job' => 'std'),
array('name' => 'Bobby' , 'year' => 1988),
array('name' => 'Sam' , 'year' => 1983),
array('name' => 'Tammy' , 'year' => 1985),
array('name' => 'Danny' , 'year' => 1983),
array('name' => 'Joe' , 'year' => 1989, 'job' => 'prof'),
);
function filter($item) {
return substr($item['name'], -1) === 'y' amp;amp; $item['year'] == 1989;
}
$filteredPeople = array_filter($people, 'filter');
print_r($filteredPeople);
// output:
Array
(
[0] => Array
(
[name] => Johnny
[year] => 1989
[job] => prof
)
[1] => Array
(
[name] => Timmy
[year] => 1989
[job] => std
)
)
Комментарии:
1. во втором примере, почему нам нужно преобразовать массив $ people? это ограничение array_filter?
2. Нет, это не ограничение
array_filter()
. Если вам не нужен$people
в исходном виде после фильтрации, вы можете смело присвоить результат$people
, т.е.$people = array_filter($people, 'filter');
.3. извините за двоичный файл . ваш код работает отлично, но я не понял,. что вы объясняете в своих комментариях здесь. можете ли вы привести больше примеров по этому поводу. большое спасибо.
4. Что вы имели в виду своим вопросом в первом комментарии (о преобразовании
$people
)? Речь шла о$filteredPeople = array_filter($people, 'filter');
строке? Если да, вы можете смело писать$people = array_filter($people, 'filter');
.