一种优雅且可重复使用的方式。
实施:
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'
)
)
)
*/