Solidity 数组删除指定位置元素及指定位置新增元素

在使用Solidity开发智能合约时,免不了使用数组,但Solidity中的数组,只提供了pushpop方法来实现尾部新增和删除元素功能,这篇文章主要讲讲实际开发中怎么实现数组删除指定位置元素及指定位置新增元素。

一、数组删除指定位置元素

1. 默认delete操作符

java 复制代码
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract ArrayRemoveItem {
    uint[] public arr = [1,2,3,4,5];

    function remove(uint index) public {
        require(index < arr.length, "index not found");
        delete arr[index];
    }

    function getLength() public view returns(uint) {
        return arr.length;
    }
}

这种操作有个问题是,它会把指定位置的元素恢复默认值,如这里uint类型的默认值是0

我们执行remove(1)操作之后,arr的值为[1,0,3,4,5],并且执行getLength()值为5

这种方法的缺点是如果0本身在我们数组中是有意义的,那最终删除了之后值也是0就会导致最终的智能合约逻辑有问题。并且数组长度可能越来越长。

2. 和末尾元素交换位置,并删除末尾位置元素

java 复制代码
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract ArrayRemoveItem {
    uint[] public arr = [1,2,3,4,5];

    function remove(uint index) public {
        require(index < arr.length, "index not found");
        arr[index] = arr[arr.length - 1];
        arr.pop();
    }

    function getLength() public view returns(uint) {
        return arr.length;
    }
}

通过把末尾元素值先赋值给目标元素,再删除末尾元素实现删除目标元素的功能。

执行remove(1)操作后,arr的值为[1,5,3,4],执行getLength()值为4。

这种方法的缺点是我们删除中间一个元素后,数组的顺序会有变化,如果我们数组本身顺序是有意义的(如按照时间排序的),那最终也会导致我们智能合约逻辑有问题。

3. 目标元素后面所有元素向前移动一位

java 复制代码
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract ArrayRemoveItem {
    uint[] public arr = [1,2,3,4,5];

    function remove(uint index) public {
        require(index < arr.length, "index not found");
        for(uint i = index; i < arr.length - 1; i++) {
            arr[i] = arr[i + 1];
        }
        arr.pop();
    }

    function getLength() public view returns(uint) {
        return arr.length;
    }
}

要想删除目标元素也不改变原本数组位置,可以通过把目标元素后面所有元素向前移动一位,再删除最后一个元素来实现删除目标元素。

执行remove(1)后,arr的值为[1,3,4,5],并且执行getLength()值为4,得到的结果全是我们想要的。

但这种方法也有缺点,就是花费的gas费较高。

所以没有完美的方法,大家可以根据自己业务开发中实际需要选择,如果在你的业务中数组顺序无意义,推荐使用第二种方法(和尾部元素交互位置,删除位置元素),如果你的业务中是数组顺序有意义,推荐使用第三种方法。

二、指定位置新增元素

java 复制代码
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract ArrayRemoveItem {
    uint[] public arr = [1,2,3,4,5];

    function remove(uint index) public {
        require(index < arr.length, "index not found");
        for(uint i = index; i < arr.length - 1; i++) {
            arr[i] = arr[i + 1];
        }
        arr.pop();
    }

    function add(uint index, uint value) public {
        require(index < arr.length, "index not found");
        arr.push();
        for(uint i = arr.length - 1; i > index; i--) {
            arr[i] = arr[i - 1];
        }
        arr[index] = value;
    }

    function getLength() public view returns(uint) {
        return arr.length;
    }
}

指定位置新增元素的原理和上面删除差不多,先把新增一个空元素,然后把指定位置后面的所有元素向后移动一位,再把新值指定位置元素就完成了。

同样的缺点,消耗gas费较多哦。

这样就可以实现Solidity中数组删除指定位置元素和指定位置新增元素,具体选哪种方法,大家可以肯定自己实际业务需要选择。

相关推荐
Roun316 小时前
去中心化存储:Web3中的数据安全新标准
web3·去中心化·区块链
请不要叫我菜鸡20 小时前
分布式——一致性模型与共识算法
分布式·后端·区块链·raft·共识算法·zab
BlockOne1121 小时前
Meme 币生态全景图分析:如何获得超额收益?
大数据·人工智能·区块链
霸都小魔女21 小时前
MT4交易的平仓与强制平仓有哪几种情况
大数据·人工智能·区块链
dingzd951 天前
Web3对社交媒体的影响:重新定义用户互动方式
web3·去中心化·区块链·媒体
复业思维202401081 天前
2024年10月第4个交易周收盘总结(10月收盘)
区块链
倾城璧1 天前
solidity中的Error和Modifier详解
区块链
搬砖的小码农_Sky1 天前
什么是区块链中的不可能三角?
区块链
web3探路者1 天前
加密货币行业与2024年美国大选
java·大数据·web3·区块链·团队开发·开源软件
yoona10202 天前
《女巫攻击:潜伏在网络背后的隐秘威胁与防御策略》
网络·web安全·区块链·学习方法·女巫攻击