Возможный дубликат:
Сопоставление шаблонов по типу массива
Мне нужно получить все элементы в массиве с определенным шаблоном ключа. Например, в этом массиве:
$items = array( "a" => "1", "b" => "2", "special_1" => "3", "c" => "4", "special_2" => "5", "special_3" => "6", "d" => "7" );
Мне нужны все элементы с ключом, содержащим строку special_
. Они должны определить новый массив:
$special_items = array( "special_1" => "3", "special_2" => "5", "special_3" => "6", );
Есть ли разумный метод, кроме цикла while?
Как насчет этого?
$special_items = array(); foreach($items as $key => $val) { if(substr($key, 0, 8) == 'special_') $special_items[$key] = $val; }
Сначала вам нужно получить массив, содержащий ключи. array_keys
Затем вам нужно отфильтровать ключи, чтобы найти нужные. array_filter
Используйте этот обратный вызов:
function($a) {return substr($a,0,8) == "special_";}
Затем переверните массив таким образом, чтобы клавиши снова были ключами вместо значений. array_flip
Наконец, пересечь эти ключи с исходным массивом. array_intersect_key
Результат:
$special_items = array_intersect_key($items,array_flip(array_filter(array_keys($items),function($a) {return substr($a,0,8) == "special_";})));
Вы можете использовать FilterIterator
$iterator = new SpecialFilter($items, 'special'); var_dump(iterator_to_array($iterator));
Вывод
array 'special_1' => string '3' (length=1) 'special_2' => string '5' (length=1) 'special_3' => string '6' (length=1)
Используемый класс
class SpecialFilter extends FilterIterator { private $f; public function __construct(array $items, $filter) { $object = new ArrayObject( $items ); $this->f = $filter; parent::__construct( $object->getIterator() ); } public function accept() { return 0 === strpos( $this->getInnerIterator()->key(), $this->f ); } }
как насчет
$keys = preg_grep( "/special_/i", array_keys( $items ) ); $new_array = array(); foreach( $keys as $k ) { $new_array[ $k ] = $items[ $k ]; }
$special_items = array_intersect_key(array_flip(preg_grep('/^special_\d+/', array_keys($items))), $items);
Пожалуйста, на самом деле не используйте это. Просто используйте цикл foreach с инструкциями strpos + if, как и все нормальные люди.