我有数组对象,希望按特定键获得2个前一个和下一个数组。
Array
(
[467] => stdClass Object
(
[id] => 467
[user_id] => 1
)
[468] => stdClass Object
(
[id] => 468
[user_id] => 1
)
[469] => stdClass Object
(
[id] => 469
[user_id] => 1
)
[474] => stdClass Object
(
[id] => 474
[user_id] => 1
)
[475] => stdClass Object
(
[id] => 475
[user_id] => 1
)
[479] => stdClass Object
(
[id] => 479
[user_id] => 1
)
[480] => stdClass Object
(
[id] => 480
[user_id] => 1
)
)
如果键定义474将导致:
我尝试这种方法,但没有工作。
$val = 474;
$currentKey = array_search($val, $array);
$before = (isset($array[$currentKey - 2])) ? $array[$currentKey - 2] :
$after = (isset($array[$currentKey + 2])) ? $array[$currentKey + 2] : $array[0];
var_dump($before, $after);
请帮忙。
答案 0 :(得分:5)
我的方法将做的是,搜索$key
值并在数组中返回其offset
。你在输入数组的值上使用array_search()
,这就是它变平的地方。
然后,如果offset
值不为假,我尝试从输入数组中切片5个所需的子数组。如果它没有返回5,则失败。
如果子数组的集合小于5,则第二个代码不会触发失败。
代码:(Demo)
$array=[
467=>(object)['id'=>467,'user_id'=>1],
468=>(object)['id'=>468,'user_id'=>1],
469=>(object)['id'=>469,'user_id'=>1],
474=>(object)['id'=>474,'user_id'=>1],
475=>(object)['id'=>475,'user_id'=>1],
479=>(object)['id'=>479,'user_id'=>1],
480=>(object)['id'=>480,'user_id'=>1]
];
$key=480;
// require 5 subarrays or none:
if(($offset=array_search($key,array_keys($array)))<2 || sizeof($result=array_slice($array,$offset-2,5))!=5){
echo "Fail";
}else{
var_export($result);
}
echo "\n---\n";
// allow any number of subarrays up to 5:
if(($offset=array_search($key,array_keys($array)))===false){
echo "Fail";
}else{
// adjust $offset and $length values to handle array "overflow"
if($offset<2){
$length=$offset+3;
}elseif(($diff=sizeof($array)-$offset)<3){
$length=$diff+2;
}else{
$length=5;
}
$offset=max(0,$offset-2);
var_export(array_slice($array,$offset,$length));
}
输出:
Fail
---
array (
0 =>
stdClass::__set_state(array(
'id' => 475,
'user_id' => 1,
)),
1 =>
stdClass::__set_state(array(
'id' => 479,
'user_id' => 1,
)),
2 =>
stdClass::__set_state(array(
'id' => 480,
'user_id' => 1,
)),
)
这是一个直观表示,以及对第二种方法正在做什么的更多解释:
以下说明使用6元素数组来演示计算。
I = 'elements labeled by their indices'
S = 'the slice'
T = 'target index'
L = 'length of slice'
I ST ST ST ST ST ST When $target index is:
0 ╗0 ╗ ╗ 0, then $offset=0 and $length=3
1 ║ ║1 ║ ╗ 1, then $offset=0 and $length=4
2 ╝ ║ ║2 ║ ╗ 2, then $offset=0 and $length=5
3 ╝ ║ ║3 ║ ╗ 3, then $offset=1 and $length=5
4 ╝ ║ ║4 ║ 4, then $offset=2 and $length=4
5 ╝ ╝ ╝5 5, then $offset=3 and $length=3
L: 3 4 5 5 4 3
答案 1 :(得分:1)
由于您的数组不在序列中,请尝试使用Demo。
$arr = array( 467 => (object) ['id' => 467, 'user_id' => 1],
468 => (object) ['id' => 468, 'user_id' => 1],
469 => (object) ['id' => 469, 'user_id' => 1],
474 => (object) ['id' => 474, 'user_id' => 1],
475 => (object) ['id' => 475, 'user_id' => 1],
479 => (object) ['id' => 479, 'user_id' => 1],
480 => (object) ['id' => 480, 'user_id' => 1],);
$find = 474;
$before2 = $before1 = $next1 = $next2 = array();
$flag = false;
foreach ($arr as $key => $val) {
if($key == $find) {
$flag = true;
}
if(!$flag) {
if(!empty($before1)){
$before2 = $before1;
}
$before1 = $val;
}
if($key != $find) {
if($flag && empty($next2)){
if(!empty($next1)){
$next2 = $next1;
}
$next1 = $val;
}
if(!empty($next2)){
break;
}
}
}
if($flag) {
echo "matching values =>";
var_dump($before2);
var_dump($before1);
var_dump($next1);
var_dump($next2);
} else {
echo "given index not found!";
}