我需要进行快速查找以查找数组中是否存在数组。如果我知道阵列的深度它会很容易 - 而且速度很快!
$heystack['lev1']['lev2']['lev3'] = 10; // $heystack stores 10,000s of arrays like this
if(isset($heystack[$var1][$var2][$var3])) do something...
如果你不知道深度,你会如何动态地做到这一点?在每个级别进行循环和搜索对于我的应用来说太慢了。
答案 0 :(得分:1)
你的问题已经答案了:
if (isset($heystack[$var1][$var2][$var3]))
{
# do something...
}
如果您不知道自己拥有多少$var1 ... $varN
,那么您只能动态地执行此操作,这涉及循环或eval
,并且取决于您是否需要处理字符串或数字键。这已经被问及并回答:
如果您担心速度,例如如果数组总是相同但你需要经常查询它,首先创建一个具有复合键的索引,这样你就可以更容易地查询它。这可以通过在递归遍历数组时存储所有键来完成:
class CompoundKeys extends RecursiveIteratorIterator
{
private $keys;
private $separator;
public function __construct($separator, RecursiveIterator $iterator, $mode = RecursiveIteratorIterator::SELF_FIRST, $flags = 0)
{
$this->separator = $separator;
parent::__construct($iterator, $mode, $flags);
}
public function current()
{
$current = parent::current();
if (is_array($current))
{
$current = array_keys($current);
}
return $current;
}
public function key()
{
$depth = $this->getDepth();
$this->keys[$depth] = parent::key();
return implode('.', array_slice($this->keys, 0, $depth+1));
}
}
用法:
$it = new CompoundKeys('.', new RecursiveArrayIterator($array));
$compound = iterator_to_array($it, 1);
isset($compound["$var1.$var2.$var3"]);
或者,这可以通过递归遍历并引用原始数组值来完成:
/**
* create an array of compound array keys aliasing the non-array values
* of the original array.
*
* @param string $separator
* @param array $array
* @return array
*/
function array_compound_key_alias(array &$array, $separator = '.')
{
$index = array();
foreach($array as $key => &$value)
{
if (is_string($key) && FALSE !== strpos($key, $separator))
{
throw new InvalidArgumentException(sprintf('Array contains key ("%s") with separator ("%s").', $key, $separator));
}
if (is_array($value))
{
$subindex = array_compound_key_alias($value, $separator);
foreach($subindex as $subkey => &$subvalue)
{
$index[$key.$separator.$subkey] = &$subvalue;
}
}
else
{
$index[$key] = &$value;
}
}
return $index;
}
用法:
$index = array_compound_key_alias($array);
isset($index["$var1.$var2.$var3"]);
答案 1 :(得分:0)
你需要一些类型的循环,但你不需要遍历整个深度。您可以简单地使用相当于$heystack[$var1][$var2][$var3]
的函数,但动态:
$heystack['lev1']['lev2']['lev3'] = 10;
echo getElement($heystack, array('lev1', 'lev2', 'lev3')); // you could build second parameter dynamically
function getElement($array, $indexes = array())
{
foreach ($indexes as $index) {
$array = $array[$index];
}
return $array;
}
// output: 10
你需要加入一些防御机制来使函数更加健壮(对于不存在的元素/索引),但这是基本的方法。