Solidity 数组中删除特定位置元素和插入新元素的操作
Solidity 智能合约开发中,数组是不可避免的数据结构之一。然而,Solidity数组仅提供了push和pop方法用于在尾部进行元素的添加和删除。本文旨在讨论如何在实际开发中实现对数组中特定位置元素的删除和新增。
一、数组删除指定位置元素
1. 默认delete
操作符
// 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. 和末尾元素交换位置,并删除末尾位置元素
// 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. 目标元素后面所有元素向前移动一位
// 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;
}
}