我有一个数组,其中键是时间戳,值是 id。
例如:
[11111111] => 11
[12345678] => 21
[12345679] => 4
[12345688] => 2
[22222222] => 1
如果我有两个时间戳,例如 12345677 和 12345689,那么找到在这两个值之间具有键的项目的最有效方法是什么?例如,返回的项目将是 21、4 和 2,但我正在处理一个大型数据集(200000 多个项目),因此它必须是高效的。
function getMiddlePart($array, $startTime, $tillTime){
$returnvalues = array();
asort( $array ); // sort the array (if needed, otherwise remove this)
// loop forward through the array until proper time is found
while( key(current($array)) < $startTime){ next($array); }
// check if we didnt end at the last one:
if( key(current($array)) !== key( end($array)){
// while the $tilltime isnt exeded, store in array:
while( key(next($array))<= $tillTime){
$returnvalues[] = current($array); // store current value
}
}
// return array. Can be length===0
return $returnvalues;
}
这个函数通过改变数组的指针来工作,next()
直到找到一个大于 $startTime 的时间。
在写这篇文章时,我注意到第一个指针是错误的,在我的下一次编辑中更正了
*我正在寻找一种改进将指针移动到正确位置的方法,所以如果有人有好的建议,请留下评论:)
简单地解释一个指针:
指针是代码中的一条信息,它记住你在数组中的位置。如果您不对数组执行任何操作,则指针位于第一项。如果您使用 a 循环遍历它foreach()
,它会将指针设置为下一个值,这就是您可以在该循环中使用相同变量名的原因。
$array[1] = 'aaa';
$array[2] = 'bbb';
$array[3] = 'ccc';
$array[4] = 'ddd';
$array[5] = 'eee';
echo current($array); // will output: aaa
next(array); // move pointer to the next item
echo current($array); // will now output: bbb
end(array); // set to last item
echo current($array); // will now output: eee
reset(array); // reset, will go back to first item:
echo current($array); // will now output: aaa
对于非常大的数据集,这不是最快的方法,您可以这样做:
$curKey = key( current($array) ); // get first key
$arrLength = count($array);
$offsetLarge = $arrLength * 0.1; // 10% keys per step
$offsetSmall = $arrLength * 0.05; // 5% keys per step
while( $array[$curKey ] < $startTime ){
$curKey += $offsetLarge; // INcrease untill limit is met
}
// we are now roughly above it
while( $array[$curKey ] > $startTime ){
$curKey -= $offsetSmall; // DEcrease untill limit is met
}
//if you want to proceed in smaller steps:
$offsetLarge *= 0.1; // 1% keys per loop
$offsetSmall *= 0.1; // 1% keys per loop
while( $array[$curKey ] < $startTime ){
$curKey += $offsetLarge; // INcrease untill limit is met
}
// we are now roughly above it
while( $array[$curKey ] > $startTime ){
$curKey -= $offsetSmall; // DEcrease untill limit is met
}
// At this point you are very close ($curKey) should be just below it and can loop up till found value.