Я столкнулся с следующей проблемой: я создал веб-сайт, представляющий «Библиотеку значков». Он в основном показывает содержимое файла CSV, содержащего дополнительные атрибуты для значка, например
В конце концов все вкладывается в большой массив:
[390] => Array ( [0] => hammer [1] => Properties [2] => tools, hammer, properties [3] => [4] => done [png] => Array ( [0] => hammer_16x.png [1] => hammer_32x.png ) [eps] => Array ( [0] => hammer_16x.eps [1] => hammer_32x.eps ) [ico] => Array ( [0] => hammer.ico ) )
Теперь я хотел бы предоставить возможность поиска в этом массиве и фильтрации содержимого, отображаемого на веб-сайте, на основе результата поиска. Поэтому я хотел бы искать по крайней мере следующие строки:
[0] => hammer [1] => Properties [2] => tools, hammer, properties [3] => [4] => done
Любые намеки, как я могу это сделать? Большое спасибо!
Вы можете использовать array_filter
в сочетании с array_diff_assoc
. Ну вот как то так:
function filter($array, $filter_elem) { return array_filter($array, function ($v) use($filter_elem) { return count(array_diff_assoc($filter_elem, $v)) == 0; }); } $array = array( '390' => array( '0' => 'hammer', '1' => 'Properties', '2' => 'tools, hammer, properties', '3' => false, '4' => 'done', 'png' => array( '0' => 'hammer_16x.png', '1' => 'hammer_32x.png', ), 'eps' => array( '0' => 'hammer_16x.eps', '1' => 'hammer_32x.eps', ), 'ico' => array( '0' => 'hammer.ico', ), ), ... ); $filter_elem = array( '1' => 'Properties', '2' => 'tools, hammer, properties', '3' => false, '4' => 'done', ); print_r(filter($array, $filter_elem));
демонстрация
Элегантный и многоразовый способ сделать это.
class FilterableArrayCollection implements ArrayAccess { /** * The original $data from your array it contains the $items to be sorted. * The items in this array are sorted in the original order you received/read * them in. */ protected $data = array(); /** * A hash structured as key/subkeys/items * - the key is an index name -- the name of a property you have in each item * from the original data; * - the subkeys are the value of the property from each item; * - the items are variable references to items who respect the rule * $item[$key] === $subkey */ protected $index = array(); public function __construct(array $data = array()) { $this->data = $data; } public function findBy($filter, $value, $isUnique = true) { if (!isset($this->index[$filter]) { foreach ($this->data as $item) { $currentValue = $item[$filter]; if ($isUnique) { $this->index[$filter][$currentValue] = &$item; } else { $this->index[$filter][$currentValue][] = &$item; } } ksort($this->index[$filter]); } else { return($this->index[$filter][$value]); } } /* * Implement ArrayAccess interface here */ }
$data = array( array( 'filename' => 'hammer', 'tooltip' => 'Properties', 'tags' => 'tools, hammer, properties', 'state' => 'done', 'filetypes' => array( 'png' => array( 'hammer_16x.png', 'hammer_32x.png' ), 'eps' => array( 'hammer_16x.eps', 'hammer_32x.eps' ), 'ico' => array( 'hammer.ico' ) ) ), array( 'filename' => 'hammer', 'tooltip' => 'not-Properties', 'tags' => 'tools, hammer, properties', 'state' => 'in progress', 'filetypes' => array( 'png' => array( 'hammer_16x.png', 'hammer_32x.png' ), 'eps' => array( 'hammer_16x.eps', 'hammer_32x.eps' ), 'ico' => array( 'hammer.ico' ) ) ) ); $x = new FilterableArrayCollection($data); $filtered = $x->findBy('state', 'done'); var_dump($filtered); /** array( 'filename' => 'hammer', 'tooltip' => 'Properties', 'tags' => 'tools, hammer, properties', 'state' => 'done', 'filetypes' => array( 'png' => array( 'hammer_16x.png', 'hammer_32x.png' ), 'eps' => array( 'hammer_16x.eps', 'hammer_32x.eps' ), 'ico' => array( 'hammer.ico' ) ) ) */