#php #arrays #multidimensional-array
#php #массивы #многомерный массив
Вопрос:
Я хочу отфильтровать или сохранить выбранные ключи и их значения в многомерном массиве. Я попробовал несколько методов с array_columns, array_filter и т.д… но я не могу сохранить исходную структуру моего массива.
вот оригинальный пример :
Array
(
[0] => Object
(
[not_wanted_key1] => some value
[wanted_key1] => wanted value
[wanted_key2] => wanted value
[not_wanted_key3] => some value
[wanted_key3] => wanted value
)
[1] => Object
(
[not_wanted_key1] => some value
[wanted_key1] => wanted value
[wanted_key2] => wanted value
[not_wanted_key3] => some value
[wanted_key3] => wanted value
)
)
ожидаемый результат :
Array
(
[0] => Object
(
[wanted_key1] => wanted value
[wanted_key2] => wanted value
[wanted_key3] => wanted value
)
[1] => Object
(
[wanted_key1] => wanted value
[wanted_key2] => wanted value
[wanted_key3] => wanted value
)
)
Кто-нибудь может меня направить?
Комментарии:
1. Короче говоря, вы не можете, потому что это объекты, а не подмассивы.
Ответ №1:
Вы можете сделать это следующим образом:
//test data
$array[] = new stdClass;
$array[0]->not_wanted_key1 = '1';
$array[0]->not_wanted_key2 = '3';
$array[0]->wanted_key1 = '4';
$array[0]->wanted_key2 = '5';
$array[0]->wanted_key3 = '6';
print_r($array);
$map = array_flip(['wanted_key1', 'wanted_key2', 'wanted_key3']);
$res = array_map(function($item) use ($map){
return array_intersect_key((array) $item, $map);
}, $array);
print_r($res);
Вывод
//input array
Array
(
[0] => stdClass Object
(
[not_wanted_key1] => 1
[not_wanted_key2] => 3
[wanted_key1] => 4
[wanted_key2] => 5
[wanted_key3] => 6
)
)
//output array
Array
(
[0] => Array
(
[wanted_key1] => 4
[wanted_key2] => 5
[wanted_key3] => 6
)
)
Довольно просто, хитрость заключается в (array)
приведении объекта к массиву, а затем мне нравится использовать array_intersect_key
, но мне лень делать это вручную $map
, поэтому я просто переворачиваю значения, чтобы они были ключами.
Таким образом, вы можете легко добавлять / удалять ключи, которые хотите сохранить, просто добавив / удалив их из $map
.
Если вы хотите сохранить внутренний массив как объект, вы также можете преобразовать его обратно! так что измените это:
return array_intersect_key((array) $item, $map);
Для
return (object)array_intersect_key((array) $item, $map);
Вывод
Array
(
[0] => stdClass Object
(
[wanted_key1] => 4
[wanted_key2] => 5
[wanted_key3] => 6
)
)
Для ясности все, что вам нужно, это это, остальное для тестирования:
$map = array_flip(['wanted_key1', 'wanted_key2', 'wanted_key3']);
$res = array_map(function($item)use($map){return array_intersect_key((array)$item,$map);},$array);
Комментарии:
1. извините за поздний ответ, но спасибо! Это именно то, чего я хотел 🙂
Ответ №2:
array_filter()
должен выполнить работу.
Простой пример:
$original = ['a' => 2, 'b' => 5, 'c' => 6];
$filtered = array_filter($original, function($item) {
// This anonymous function must return true for keeping your item, or false for not keeping it
// There I want to keep items with a value more than 4.
return ($item > 4);
});
// Output of $filtered: ['b' => 5, 'c' => 6]
Тот же пример с массивом объектов, предположив, что они обладают value
свойством:
$filtered = array_filter($original, function($item) {
// There I want to keep items with a value more than 4.
return ($item->value > 4);
});
// Output of $filtered: ['b' => 5, 'c' => 6]
Если ваша логика заключается в фильтрации по ключам, третий параметр flag
должен быть установлен на ARRAY_FILTER_USE_KEY
. Тогда $item
это будут ваши ключи, а не значения.
Комментарии:
1. ключи, которые я хочу сохранить, одинаковы во всех объектах, но «значения» для всех них разные и не обязательно числовые. Я хочу сохранить wanted_key1, 2 и 3 и связанное с ними другое «значение»
Ответ №3:
Аналогично ответу ArtisticPheonix, перебираем и сохраняем нужные ключи, используя пересечение:
<?php
$data =
[
['fruit'=>'apple', 'veg'=>'carrot'],
['fruit'=>'banana', 'veg'=>'marrow']
];
$flipped_wanted_keys = array_flip(['fruit']);
foreach($data as amp;$item)
$item = array_intersect_key($item, $flipped_wanted_keys);
unset($item);
print_r($data);
Вывод:
Array
(
[0] => Array
(
[fruit] => apple
)
[1] => Array
(
[fruit] => banana
)
)
Поскольку у вас есть объекты в вашем массиве, удаление свойств требует другого подхода, но если вы довольны тем, что на выходе у вас многомерный массив, как указано выше, тогда вам просто нужно преобразовать ваш объект в массив перед пересечением ключей (при условии, что это доступные свойства).
$item = array_intersect_key((array) $item, $flipped_wanted_keys);