如何避免数组下标越界

简介: 数组下标越界真的是开发过程中的痛,除了在开发过程中各种判断是否设置,是否为空,还有其他优雅的办法解决吗?

抛出问题


数组下标越界真的是开发过程中的痛,除了在开发过程中各种判断是否设置,是否为空,还有其他优雅的办法解决吗?


回答问题


肯定是有的


举个栗子


比如,我有一个工具性质的方法如下:


我怎么保证 $batchUserCover[$userid]['pickedFootprint']$batchFootprintList[$userid]['list'] 不会有下标越界的问题呢?


//批量获得图片故事 优先精选故事 不足三个拼接最近发布的故事
    public static function batchImageFootprint($userIds, $batchUserCover, $batchFootprintList)
    {
        $ret = [];
        foreach ($userIds as $userid) {
            $ret[$userid] = array_slice(array_merge($batchUserCover[$userid]['pickedFootprint'], array_slice($batchFootprintList[$userid]['list'], 0, 3)), 0, 3);
        }
        return $ret;
    }


解题思路


  1. 在方法外判断是否设置值
  2. 在方法外保证已经设置值,确保 $batchUserCover[$userid]['pickedFootprint'] 这类参数一定是存在的,已经设置了的.


我认为思路2更好


解题实践


实践1:


在传入数据之前,设置好传入值,保证传入值的key必须存在,值可以为null,或者空数组。 核心代码如下:


public static function batchFormatCoverAndPickedFootprint($userListInfo)
    {
        foreach ($userListInfo as &$element) {
            $retData[$element['userid']] = [
                'pickedFootprint' => [],
                'coverFootprint' => [],
            ];
        }
        .
        .
        .
        return $retData;
    }


传入的数组的key必然符合[$userid]['pickedFootprint'],不会存在数组下标越界


$batchUserCover = batchFormatCoverAndPickedFootprint(xxx);
    self::batchImageFootprint($userIds, $batchUserCover);


实践2:


和实践1的底层思路是一致的,区别在于实践1是在函数内首先定义了符合规范的初始值


实践2是先处理业务逻辑,在return之前定义了符合规范的初始值

(下面代码段写了注释,重点看后半部分;联合查询那部分代码质量也不错,没省略掉,看能不能抛转引玉。)


public static function batchFootprintList($userIds, $pageCount = 21, $batchPickedFootprints = [], $select = 'userid,id,mid,image,text,ST_Astext(picgeom) as "picgeom",poi,poiid,city,province,country,pictime')
    {
        .
        .
        .
        //联合查询
        $union = self::query()->selectRaw($select)->where('userid', $userIds[0])
            ->where('status', self::TYPE_STATUS_NORMAL)
            ->whereNotIn('mid', $batchPickedFootprints[$userIds[0]])
            ->orderBy('id', 'desc')
            ->limit($pageCount);
        //避免重复查询第一条数据
        unset($userIds[0]);
        foreach ($userIds as $userId) {
            $unionItem = self::query()->selectRaw($select)->where('userid', $userId)
                ->where('status', self::TYPE_STATUS_NORMAL)
                ->whereNotIn('mid', $batchPickedFootprints[$userId])
                ->orderBy('id', 'desc')
                ->limit($pageCount);
            $union->unionAll($unionItem);
        }
        $allUserFootprints = $union->get()->toArray();
        $res = [];
        $chunkFootprintByUserid = self::_chunkFootprintByUserid($allUserFootprints);
        // 重点在这里
        foreach ($allUserIds as $userId) {
            $list = $chunkFootprintByUserid[$userId] ?? [];
            $count = count($list);
            //以此保证不会出现数据下标越界的问题
            $res[$userId]['list'] = $list;
            $res[$userId]['more'] = $count < $pageCount ? 0 : 1;
            $res[$userId]['track'] = $count > 0 ? (string)$list[$count - 1]['id'] : '';
        }
        return $res;
    }


相关文章
|
设计模式 运维 Java
开发中造成空指针的常见写法,如何预防!
开发中造成空指针的常见写法,如何预防!
85 0
|
7月前
|
C语言
C语言中如何避免循环死循环
C语言中如何避免循环死循环
323 1
|
7月前
|
存储 编译器 程序员
C陷阱——数组越界引发的死循环问题
C陷阱——数组越界引发的死循环问题
|
7月前
|
存储 编译器 C语言
C陷阱:数组越界遍历,不报错却出现死循环?从内存解析角度看数组与局部变量之“爱恨纠葛”
在代码练习中,通常会避免数组越界访问,但如果运行了这样的代码,可能会导致未定义行为,例如死循环。当循环遍历数组时,如果下标超出数组长度,程序可能会持续停留在循环体内。这种情况的发生与数组和局部变量(如循环变量)在内存中的布局有关。在某些编译器和环境下,数组和局部变量可能在栈上相邻存储,数组越界访问可能会修改到循环变量的值,导致循环条件始终满足,从而形成死循环。理解这种情况有助于我们更好地理解和预防这类编程错误。
162 0
|
7月前
|
存储 编译器 C语言
关于数组越界却不会报错
关于数组越界却不会报错
|
7月前
Map遍历时报ConcurrentModificationException解决方法
Map遍历时报ConcurrentModificationException解决方法
505 0
|
C++
c/c++ 那些你一定出错的数组笔试题
c/c++ 那些你一定出错的数组笔试题
57 0
|
Java
ArrayList 循环遍历并删除元素的常见陷阱
ArrayList 循环遍历并删除元素的常见陷阱
111 0
数组越界死循环问题!
数组越界死循环问题!
56 0
|
Java 索引 容器
【JavaSE专栏28】数组下标能越界?越界了如何处理?
【JavaSE专栏28】数组下标能越界?越界了如何处理?
499 0