在Lua中,table如何安全的移除元素这点挺重要,因为如果不小心,会没有正确的移除,造成内存泄漏。

引子

比如有些朋友常常这么做,大家看有啥问题

将test表中的偶数移除掉
local test = { 2, 3, 4, 8, 9, 100, 20, 13, 15, 7, 11}
for i, v in ipairs( test ) do
  if v % 2 == 0 then
    table.remove(test, i)
  end
end

for i, v in ipairs( test ) do
  print(i .. "====" .. v)
end
打印结果:

1====3
2====8
3====9
4====20
5====13
6====15
7====7
8====11
[Finished in 0.0s]
有问题吧,20怎么还在?这就是在遍历中删除导致的。

如何做呢?

Let's get started!
local test = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p' }
local remove = { a = true, b = true, c = true, e = true, f = true, p = true }

local function dump(table)
  for k, v in pairs( table ) do
    print(k)
    print(v)
    print("*********")
  end
end
说明:一般我们不在循环中删除,在循环中删除会造成一些错误。这是可以建立一个remove表用来标记将要删除的,如上面例子,把将要删除的标记为true

方法1 从后往前删除

for i = #test, 1, -1 do
  if remove[test[i]] then
    table.remove(test, i)
  end
end

dump(test)
为什么不从前往后,朋友们可以测试,table.remove操作后,后面的元素会往前移位,这时候后续的删除索引对应的元素已经不是之前的索引对应的元素了。

方法2 while删除

local i = 1
while i <= #test do
  if remove[test[i]] then
    table.remove(test, i)
  else
    i = i + 1
  end
end

dump(test)
方法3 quick中提供的removeItem

function table.removeItem(list, item, removeAll)
  local rmCount = 0
  for i = 1, #list do
    if list[i - rmCount] == item then
      table.remove(list, i - rmCount)
      if removeAll then
        rmCount = rmCount + 1
      else
        break
      end
    end
  end
end

for k, v in pairs( remove ) do
  table.removeItem(test, k)
end

dump(test)

lua中table如何安全移除元素的更多相关文章

  1. lua中 table 元表中元方法的重构实现

    转载请标明出处http://www.cnblogs.com/zblade/ lua作为游戏的热更新首选的脚本,其优势不再过多的赘述.今天,我主要写一下如何重写lua中的元方法,通过自己的重写来实现对l ...

  2. lua中 table 重构index/pairs元方法优化table内存占用

    转载请标明出处http://www.cnblogs.com/zblade/ lua作为游戏的热更新首选的脚本,其优势不再过多的赘述.今天,我主要写一下如何重写lua中的元方法,通过自己的重写来实现对l ...

  3. lua中 table.getn(t) 、#t、 table.maxn(t) 这三个什么区别?

    lua中 table.getn(t) .#t. table.maxn(t) 这三个什么区别? RTlocal t = {1,888,x= 999,b=2,5,nil,6,7,[10]=1,8,{z = ...

  4. Lua中table的实现-《Lua设计与实现》

    本文来自<Lua设计与实现>的阅读笔记,推荐Lua学习者可以购买一本,深入浅出讲解lua的设计和实现原理,很赞,哈哈   Lua中对于表的设计,是基于数组和散列表,和其他语言不同,对于数组 ...

  5. lua中table的遍历,以及删除

    Lua 内table遍历 在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: 1. ipairs for index, value in ipair ...

  6. 算法练习之合并两个有序链表, 删除排序数组中的重复项,移除元素,实现strStr(),搜索插入位置,无重复字符的最长子串

    最近在学习java,但是对于数据操作那部分还是不熟悉 因此决定找几个简单的算法写,用php和java分别实现 1.合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两 ...

  7. C++对Lua中table进行读取、修改和创建

    C++代码: // LuaAndC.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #i ...

  8. Lua中Table的学习

    --table 是 Lua 的一种数据结构,用来帮助我们创建不同的数据类型,如:数组.字典等 --Lua也是通过table来解决模块(module).包(package)和对象(Object)的. 例 ...

  9. lua中table的常用方法

    转载:https://blog.csdn.net/Fenglele_Fans/article/details/83627021 1:table.sort() language = {"lua ...

随机推荐

  1. HDUOJ----1181 变形课

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submi ...

  2. 深入浅出Android开发之Surface介绍

    一 目的 本节的目的就是为了讲清楚Android中的Surface系统,大家耳熟能详的SurfaceFlinger到底是个什么东西,它的工作流程又是怎样的.当然,鉴于SurfaceFlinger的复杂 ...

  3. Quartz2之入门示例

    环境:XP+Myeclipse6.5+JDK1.6 quartz官网:http://www.quartz-scheduler.org/ 参考资料 1 Quartz任务调度快速入门 http://www ...

  4. Python学习笔记010——函数文档字符串

    函数文档字符串documentation string (docstring)是在函数开头,用来解释其接口的字符串.简而言之:帮助文档 包含函数的基础信息 包含函数的功能简介 包含每个形参的类型,使用 ...

  5. NGUI: UIPanel控件

    转自:http://blog.csdn.net/huang9012/article/details/19411703 http://bbs.9ria.com/thread-417659-1-1.htm ...

  6. Python2 字典 cmp() 函数

    描述 Python 字典的 cmp() 函数用于比较两个字典元素,如果 dict1 < dict2 返回 -1, 如果 dict1 == dict2 返回 0, 如果 dict1 > di ...

  7. Python ceil() 函数

    描述 ceil(x) 函数返回一个大于或等于 x 的的最小整数(向上取整). 语法 以下是 ceil() 方法的语法: import math math.ceil( x ) 注意:ceil()是不能直 ...

  8. /usr/local/ssl/lib/libssl.a: error adding symbols: Bad value

    一.背景 编译第三方库A的时候提示依赖openssl库. 二.编译openssl库 去官网下载最新版本的openssl-1.0.2l.tar.gztar -zxvf openssl-1.0.2l.ta ...

  9. jenkins 执行远程linux命令

    在Jenkins中进行构建时,可能需要首先SSH登录到一个远程服务器以执行必要的脚本,然后再执行构建.这时,需要安装SSH Plugin,并进行如下配置.1.在Jenkins界面,系统管理->管 ...

  10. Redis(五):几个常用概念

    1.Redis 默认有16384 solts(槽),每个槽可以存储多个hash值. 2.Redis 默认不需要密码: 2.1 注释去掉,设置自己的密码 3.设置密码后需要通过 3.1 -h 主机ip ...