从数组对象

时间:2017-11-24 02:28:16

标签: php arrays

我有数组对象,希望按特定键获得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将导致:

  • 来自密钥469和468
  • 的上一个数组
  • 来自密钥475和479的下一个阵列组
  • 如果没有上一个和下一个数组,我想要没有结果

我尝试这种方法,但没有工作。

$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);

请帮忙。

2 个答案:

答案 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!";
}