我有以下php数组;
array(
(int) 0 => array(
'records' => array(
'id' => '25',
'parent_id' => '1',
'address' => '896167',
)
),
(int) 1 => array(
'records' => array(
'id' => '26',
'parent_id' => '2',
'address' => '890812',
)
),
(int) 2 => array(
'records' => array(
'id' => '28',
'parent_id' => '16',
'address' => '8A3813',
)
),
(int) 3 => array(
'records' => array(
'id' => '29',
'parent_id' => '17',
'address' => '8A3914',
)
)
)
假设我想找到哪个密钥有'id' => '29'
,有什么方法可以快速搜索这个数组并返回正确的密钥?在这种情况下,正确的答案是3.
编辑:有人会建议使用foreach循环遍历数组还是使用array_search会更快?或者它们的速度大致相同?
答案 0 :(得分:2)
foreach ($data as $key => $value) {
if ($value['records']['id'] == '29') break;
}
echo $key;
线性时间完成。
如果您的数组按ID排序,则可以进行二进制搜索,而不是以对数时间完成。
function binary_search($needle, $haystack) {
$min = 0;
$max = count($haystack);
while ($max >= $min)
{
$mid = (int) (($min + $max) / 2);
if ($haystack[$mid]['records']['id'] == $needle) return $mid;
else if ($haystack[$mid]['records']['id'] < $needle) $min = $mid + 1;
else $max = $mid - 1;
}
// $needle was not found
return false;
}
echo binary_search('29', $data);
答案 1 :(得分:1)
您无法在数据结构上使用array_search()
。您的foreach
解决方案的时间复杂度为O(n)
(因此也会array_search()
。)
你说记录按其ID排序。然后,您可以使用O(log(n))
执行binary search,效果更好。
答案 2 :(得分:1)
你可以使用这样的二进制搜索算法:
$searchableArray = array(
0 => array(
'records' => array(
'id' => '25',
'parent_id' => '1',
'address' => '896167',
)
),
1 => array(
'records' => array(
'id' => '26',
'parent_id' => '2',
'address' => '890812',
)
),
2 => array(
'records' => array(
'id' => '28',
'parent_id' => '16',
'address' => '8A3813',
)
),
3 => array(
'records' => array(
'id' => '29',
'parent_id' => '17',
'address' => '8A3914',
)
)
);
$foundKey = findKey( $searchableArray, 29 );
echo "Found key: " . $foundKey;
function findKey( $searchableArray, $key ){
$splittedArray = splitArray( $searchableArray );
if( isInLeftChunk( $splittedArray[0], $key ) ){
if( ! isOnlyElement( $splittedArray[0] ) ){
return findKey( $splittedArray[0], $key );
}
return key( $splittedArray[0] );
}
elseif( isInRightChunk( $splittedArray[1], $key ) ){
if( ! isOnlyElement( $splittedArray[1] ) ){
return findKey( $splittedArray[1], $key );
}
return key( $splittedArray[1] );
}
// Element not found
return false;
}
function isOnlyElement( $arrayChunk ){
return count( $arrayChunk ) == 1;
}
function isInLeftChunk( $arrayChunk, $key ){
end( $arrayChunk );
$latestKey = key( $arrayChunk );
if( is_int( $latestKey )){
return $arrayChunk[ $latestKey ]['records']['id'] >= $key;
}
return $arrayChunk[ $latestKey ]['id'] >= $key;
}
function isInRightChunk( $arrayChunk, $key ){
reset( $arrayChunk );
$firstKey = key( $arrayChunk );
if( is_int( $firstKey )){
return $arrayChunk[$firstKey]['records']['id'] <= $key;
}
return $arrayChunk[ $firstKey ]['id'] <= $key;
}
function splitArray( $unsplittedArray ){
$arrayLenght = count( $unsplittedArray );
if( $arrayLenght == 1 ){
return array_chunk( $unsplittedArray, $arrayLenght, true );
}
$odd = $arrayLenght % 2 != 0;
if( $odd ){
$arrayLenght += 1;
}
$arrayLenght = $arrayLenght * 0.5;
return array_chunk( $unsplittedArray, $arrayLenght, true );
}
答案 3 :(得分:1)
如果要进行许多这样的搜索,最好创建一个反向查找数组。
也就是说,您一次完成缓慢的线性工作 ,之后,它是快速的哈希(关联数组)查找。
一次:
$id2index = array();
foreach ($data as $index => $value) {
$id2index[$value->id] = $index;
}
已使用多次-查找给定ID的索引:
$index = $id2index[$id];