简体   繁体   English

如何在 Solidity 中优化此智能合约 function 关于删除数组特定索引中的元素

[英]How to optimize this smart contract function in Solidity about deleting an element in particular index of an array

I used the following library code to delete an element in array according to its index.我使用以下库代码根据其索引删除数组中的元素。 The only way in my mind is using loop, but it costs a lot of gas.在我看来,唯一的方法是使用循环,但它会消耗大量气体。 Is there any other optimized code to solve this problem?还有其他优化代码可以解决这个问题吗?

library ArrayLibrary {
    function remove(uint[] storage _arr, uint _removedIndex) public returns(uint[] memory){
        require(_arr.length > 0, "No element in Array.");
        for(uint i; i < _arr.length - 1; i++){
            if (i >= _removedIndex) {
                _arr[i] = _arr[i + 1];               
            } 
        }
        _arr.pop();
        return _arr;
    }
}


contract TestLibrary {
    uint[] arr;
    using ArrayLibrary for uint[];

    function deleteArrEle(uint[] calldata _arr, uint deletedIndex) public returns (uint[] memory deletedArr) {
        arr = _arr;
        deletedArr = arr.remove(deletedIndex);
    }
}

If you don't mind switching order of the items, you can copy the last item to the position of the unwanted item and then remove the last.如果您不介意调换项目的顺序,您可以将最后一项复制到不需要的项目的 position,然后删除最后一项。

function remove(uint[] storage _arr, uint _removedIndex) public returns(uint[] memory){
    require(_arr.length > 0, "No element in Array.");
    _arr[_removedIndex] = _arr[_arr.length-1];
    _arr.pop();
    return _arr;
}

Input array [1,2,3,4] , removing at index 1 (value 2).输入数组[1,2,3,4] ,从索引 1(值 2)处删除。 Output [1,4,3] . Output [1,4,3]


There is also a bit more complex workaround with linked sorted list.链接排序列表还有一些更复杂的解决方法。 Example code in Liquity protocol's SortedTroves for example.例如,Liquity 协议的SortedTroves中的示例代码。

The sorted data is not stored in an array but in a mapping of structs that point to previous and next items.排序后的数据不存储在数组中,而是存储在指向上一个和下一个项目的结构映射中。

  • key A:关键一:
    • value 1值 1
    • link to previous key: empty (meaning there's no previous value)链接到上一个键:空(意味着没有以前的值)
    • link to next key: D链接到下一个键:D
  • key C:密钥 C:
    • value 7值 7
    • link to previous key: D链接到上一个密钥:D
    • link to next key: empty (meaning there's no next key)链接到下一个键:空(意味着没有下一个键)
  • key D:关键D:
    • value 5值 5
    • link to previous key: A链接到上一个密钥:A
    • link to next key: C链接到下一个密钥:C

The contract also holds info about keys of lowest and highest value.该合同还包含有关最低和最高价值的密钥的信息。

When you're removing an item, you only remove this specific item, and change the 2 links (next and previous) that originally pointed to this item.当您删除一个项目时,您只会删除这个特定项目,并更改最初指向该项目的 2 个链接(下一个和上一个)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM