• (原创) cocos2d-x 3.0+ lua 学习和工作(5) : table的remove的坑


    本章主要讲下,table的remove,这个东西不注意就容易被坑(被坑的飘过~~~),当然,这里是针对数组table。即用ipairs方法遍历。

    星月倾心贡献~~~

    看示例1:直接nil

    local tbl = { 1, 2, 3, 4, 5 }
    
    for k, v in ipairs( tbl ) do 
        if v == 3 then
            tbl[k] = nil
        else
            print( "one: " .. k .. ":" .. v )
        end
        
    end
    
    -- 再次输出会发什么。。。
    for k, v in ipairs( tbl ) do 
        print( "two" .. k .. ":" .. v )
    end
    
    
    输出:
    one: 1:1
    one: 2:2
    one: 4:4
    one: 5:5
    
    -- 没有输出3
    
    再次输出:
    two1:1
    two2:2
    -- 只输出了,12

    大家可以看到,再次输出时,只输出了1,2。(小白:为什么。。。)

    我们在直接nil后,table的元素变成了{ [1] = 1, [2] = 2, [4] = 4, [5] = 5 },我之前已经知道,ipairs是连续顺序遍历的,查找3,不存在,结束遍历。(小白:对哦~~)

    直接nil,table中的其他元素key值不会改变~~~(坑。。。)

    那么有没有方法删除后,table元素重新依次排列?

    这个就是我没要讲的第二个方法:table.remove()

    示例2:table.remove方法删除

    local tbl = { 1, 2, 3, 4, 5 }
    
    for k, v in ipairs( tbl ) do 
        if v == 3 then
            table.remove( tbl, k )
        else
            print( "one: " .. k .. ":" .. v )
        end
        
    end
    
    -- 再次输出会发什么。。。
    for k, v in ipairs( tbl ) do 
        print( "two" .. k .. ":" .. v )
    end
    
    输出:
    one: 1:1
    one: 2:2
    one: 4:5  -- 1. 注意,这里只输出了 vlaue: 5
    
    -- 没有输出3
    
    再次输出:
    two1:1
    two2:2
    two3:4  -- 2. 注意:key: 3
    two4:5  -- 3. 注意:key: 4 
    
    -- 再次输出后,key值是连续的

    我们先看再次输出,再次输出可以看到所有的元素都输出了,并且key值是连续的。这就是table.remove删除方法的好处。这个没有问题~~~

    现在问题来了,大家注意。(小白:什么问题。。。)

    在第一个输出中,注释中可以看到只输出了5,没有输出4。(小白:什么...value: 4去那里了???)

    这就是另外一个坑了~~~~(小白:好坑~~~)你以为它遍历了所有,其实它漏人了。。。

    原因是:

    table.remove会自动帮我们排序,remove后的tbl是 { 1, 2, 4, 5 }

    但是在第一个for循环中,remove时候,k == 3,再次进入下一个语句时,k == 4, 这时的tbl[4] == 5,然后k达到最大值,结束循环。所以只输出了5,没有输出4。

    小白:这个bug很简单啊,我在remove后,让 k = k - 1;这样再次进入下一个语句时,k就等于3了,就能输出4了。

    星月:是吗?(小白:难道不是吗...?)

    为了让小白死心,这里分析下k的值。

    k的值是ipairs迭代器返回的值,就算将k = k - 1, 即人为让 k = 2 了,那么下一个调用时,迭代器仍然返回 4,即 k = 4。所以在外界改变k的值没有任何意义。(再坑一次~~~~)

    (小白:好坑~~~那怎么办???)

    那么有什么办法解决这个呢?

    示例3:逆查找,然后调用table.remove

    local tbl = { 1, 2, 3, 4, 5 }
    
    for k = #tbl, 1, -1  do 
        if tbl[k] == 3 then
            table.remove( tbl, k )
        else
            print( "one: " .. k .. ":" .. tbl[k] )
        end
        
    end
    
    -- 再次输出会发什么。。。
    for k, v in ipairs( tbl ) do 
        print( "two" .. k .. ":" .. v )
    end
    
    
    输出:
    one: 5:5
    one: 4:4
    one: 2:2
    one: 1:1
    
    -- 这里所有元素全部输出了!!
    
    -- 没有输出3
    
    再次输出:
    two1:1
    two2:2
    two3:4  -- 2. 注意:key: 3
    two4:5  -- 3. 注意:key: 4 
    
    -- 再次输出后,key值是连续的!!

    可以第一次输出所有元素都输出了,第二次也所有元素都输出了。(小白:真的耶~~~)(星月:呕吐...)

    原来大家自己分析,跟示例2的原理差不多。

    本章到此结束,希望对大家有帮助。

    星月倾心贡献~~~

    作者使用 cocos2d-x 3.0 + lua学习和工作心得,未经作者允许,请勿转载!在此谢谢各位手下留情~~~

    本文没有获得作者本人同意,不得转载,否则必追究相关责任。转载请注明出处!!~~

    原文地址:http://www.cnblogs.com/wodehao0808/p/4029560.html 

  • 相关阅读:
    OpenCV--图像特征(harris角点检测)
    pycharm处理命令行参数
    OpenCV--文档扫描OCR识别
    OpenCV--信用卡数字识别
    OpenCV--傅里叶变换
    OpenCV--直方图
    OpenCV--模板匹配
    OpenCV--图像轮廓
    OpenCV--图像金字塔
    51Nod-1288 汽油补给 ST表 贪心 模拟
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/4029560.html
Copyright © 2020-2023  润新知