Как отфильтровать массив по условию
-
19-09-2019 - |
Вопрос
У меня есть такой массив:
array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2)
Теперь я хочу отфильтровать этот массив по некоторому условию и сохранить только те элементы, значение которых равно 2, и удалить все элементы, значение которых НЕ равно 2.
Итак, мой ожидаемый массив результатов будет:
array("a" => 2, "c" => 2, "f" => 2)
Примечание:Я хочу сохранить ключи из исходного массива.
Как я могу сделать это с помощью PHP?Есть встроенные функции?
Решение
$fullarray = array('a'=>2,'b'=>4,'c'=>2,'d'=>5,'e'=>6,'f'=>2);
function filterArray($value){
return ($value == 2);
}
$filteredArray = array_filter($fullArray, 'filterArray');
foreach($filteredArray as $k => $v){
echo "$k = $v";
}
Другие советы
Вам каким-то образом придется перебирать массив и фильтровать каждый элемент по вашему условию.Это можно сделать различными методами.
Петли while
/ for
/ foreach
метод
Прокрутите свой массив с помощью любого цикла, который вы хотите, может быть while
, for
или foreach
.Затем просто проверьте свое состояние и либо unset()
элементы, если они не соответствуют вашему условию, или запишите элементы, соответствующие условию, в новый массив.
Зацикливание
//while loop
while(list($key, $value) = each($array)){
//condition
}
//for loop
$keys = array_keys($array);
for($counter = 0, $length = count($array); $counter < $length; $counter++){
$key = $keys[$counter];
$value = $array[$key];
//condition
}
//foreach loop
foreach($array as $key => $value){
//condition
}
Состояние
Просто поместите свое условие в цикл, где находится комментарий //condition
является.Условие может просто проверить все, что вы хотите, а затем вы можете либо unset()
элементы, которые не соответствуют вашему условию, и переиндексируйте массив с помощью array_values()
если хотите, или запишите в новый массив элементы, соответствующие условию.
//Pseudo code
//Use one of the two ways
if(состояние){ //1. Condition fulfilled
$newArray[ ] = $value;
//↑ Put '$key' there, if you want to keep the original keys
//Result array is: $newArray
} else { //2. Condition NOT fulfilled
unset($array[$key]);
//Use array_values() after the loop if you want to reindex the array
//Result array is: $array
}
array_filter()
метод
Другой метод заключается в использовании array_filter()
встроенная функция.Обычно он работает почти так же, как метод с простым циклом.
Вам просто нужно вернуться TRUE
если вы хотите сохранить элемент в массиве и FALSE
если вы хотите удалить элемент из массива результатов.
//Anonymous function
$newArray = array_filter($array, function($value, $key){
//condition
}, ARRAY_FILTER_USE_BOTH);
//Function name passed as string
function filter($value, $key){
//condition
}
$newArray = array_filter($array, "filter", ARRAY_FILTER_USE_BOTH);
//'create_function()', NOT recommended
$newArray = array_filter($array, create_function('$value, $key', '/* condition */'), ARRAY_FILTER_USE_BOTH);
preg_grep()
метод
preg_grep()
похож на array_filter()
просто для фильтрации массива он использует только регулярное выражение.Таким образом, вы, возможно, не сможете сделать с ним все, поскольку вы можете использовать только регулярное выражение в качестве фильтра и фильтровать только по значениям или с дополнительным кодом по ключам.
Также обратите внимание, что вы можете передать флаг PREG_GREP_INVERT
в качестве третьего параметра для инвертирования результатов.
//Filter by values
$newArray = preg_grep("/регулярное выражение/", $array);
Общие условия
Существует множество общих условий, используемых для фильтрации массива, все из которых могут быть применены к значению и/или ключу массива.Я просто перечислю здесь некоторые из них:
//Нечетные значения
return $value & 1;
//Четные значения
return !($value & 1);
//НЕ нулевые значения
return !is_null($value);
//НЕ 0 значений
return $value !== 0;
//Содержать определенные значения значений
return strpos($value, $needle) !== FALSE; //Use 'use($needle)' to get the var into scope
//Содержать определенную подстроку в значениях позиций
return substr($value, $position, $length) === $subString;
//НЕТ «пусто» (ссылка) ценности
array_filter($array); //Leave out the callback parameter
Вы можете перебирать копии ключей, чтобы иметь возможность использовать unset()
в петле:
foreach (array_keys($array) as $key) {
if ($array[$key] != 2) {
unset($array[$key]);
}
}
Преимущество этого метода — эффективность использования памяти, если ваш массив содержит большие значения — они не дублируются.
РЕДАКТИРОВАТЬ Я только что заметил, что на самом деле вам нужны только ключи со значением 2 (значение вы уже знаете):
$keys = array();
foreach ($array as $key => $value) {
if ($value == 2) {
$keys[] = $key;
}
}
Это должно сработать, но я не уверен, насколько это эффективно, поскольку вы, вероятно, в конечном итоге скопируете много данных.
$newArray = array_intersect_key(
$fullarray,
array_flip(array_keys($fullarray, 2))
);
Я думаю, что самая быстрая и читаемая встроенная функция: array_intersect()
Код:(Демо)
$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
var_export(array_intersect($array, [2]));
Выход:
array (
'a' => 2,
'c' => 2,
'f' => 2,
)
Просто убедитесь, что вы объявили второй параметр как массив, потому что это ожидаемый тип значения.
Теперь нет ничего плохого в написании цикла foreach или использовании array_filter()
, у них просто более подробный синтаксис.
array_intersect()
также очень легко расширить (включить дополнительные «уточняющие» значения), добавив дополнительные значения во второй массив параметров.
foreach ($aray as $key => $value) {
if (2 != $value) {
unset($array($key));
}
}
echo 'Items in array:' . count($array);
Я мог бы сделать что-то вроде:
$newarray = array();
foreach ($jsonarray as $testelement){
if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);