有没有人知道如何删除数组中的元素? 有没有内置的方法来做这个?

如果没有的话,有谁知道怎样实现这样的方法?

原文地址

4 人回答 0

4 个回答
投票数
最旧发布
最近发布

回答发布于 2018-09-11 21:25:15

使用delete运算符删除元素:

delete array[index];

如果你不想留下间隙,那就需要手动移动每个元素:

contract test{
    uint[] array = [1,2,3,4,5];
    function remove(uint index)  returns(uint[]) {
        if (index >= array.length) return;

        for (uint i = index; i<array.length-1; i++){
            array[i] = array[i+1];
        }
        delete array[array.length-1];
        array.length--;
        return array;
    }
}

如果你不关心顺序,也可以把最后一个元素复制到空出来的地方,然后删除最后一个元素。

||
||

回答发布于 2018-09-11 21:25:14

对Tjaden Hess回答的一点优化:

contract Test {
    uint[] array = [1,2,3,4,5];
    function remove(uint index)  returns(uint[]) {
        if (index >= array.length) return;

        for (uint i = index; i<array.length-1; i++){
            array[i] = array[i+1];
        }
        array.length--;
        return array;
    }
}

我删除了在array.length--;之前的行delete array[array.length-1];。这减少了函数5000gas的消耗。当数组长度减少时,编译器会自动清理未占用的空间。双重存储重置可以增加5000gas。

||
||

回答发布于 2018-09-11 21:25:13
pragma solidity ^0.4.11;
contract TestArray {
    uint[] public original;
    uint[] public newOr;
    event Log(uint n, uint a, uint b, uint c);

    function TestArray(){
        original.push(1);
        original.push(2);
        original.push(3);
        original.push(4);

    }

    function test(){
        newOr = remove(original, 1);
        Log(newOr.length, newOr[0], newOr[1], newOr[2]);
    }
    function remove(uint[] array, uint index) internal returns(uint[] value) {
        if (index >= array.length) return;

        uint[] memory arrayNew = new uint[](array.length-1);
        for (uint i = 0; i<arrayNew.length; i++){
            if(i != index && i<index){
                arrayNew[i] = array[i];
            } else {
                arrayNew[i] = array[i+1];
            }
        }
        delete array;
        return arrayNew;
    }

}
||
||

回答发布于 2018-09-11 21:25:12

删除a是把类型的初始值赋给a,也就是说对于整数,它等价于a=0,但它也可以用在数组上,即指定一个长度为零的动态数组或一个相同长度的静态数组,并重置所有元素。对于结构体,它分配一个所有成员重置了的结构体。

>我已经实现了它,通过这个简单的例子可能有助于理解

**

如果我们使用索引删除元素,它将不会留下空白。

**

http://solidity.readthedocs.io/en/v0.4.21/types.html

contract UserRecord {
    constructor() public { owner = msg.sender; }

    address owner;

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    struct User {
        bytes32 userEmail;
        uint index;
    }

    mapping (bytes32 => User) private users;

    bytes32[] private usersRecords;
    event LogNewUser(bytes32 indexed userEmail, uint index);

    function setUseremail(bytes32 _userEmail) public onlyOwner returns(bool success){
        users[_userEmail].userEmail = _userEmail;
        users[_userEmail].index = usersRecords.push(_userEmail) -1;

        emit LogNewUser(
        _userEmail,
        users[_userEmail].index
        );
        return true;
    }

//this will delete the user at particular index and gap will be not there

    function deleteUser(bytes32 _userEmail) public onlyOwner returns(uint index){
        require(!isUser(_userEmail)); 
        uint toDelete = users[_userEmail].index;
        bytes32 lastIndex = usersRecords[usersRecords.length-1];
        usersRecords[toDelete] = lastIndex;
        users[lastIndex].index = toDelete; 
        usersRecords.length--;
        return toDelete;   
    }    
}
||
||

回答发布于 2018-09-11 21:25:12

删除a是把类型的初始值赋给a,也就是说对于整数,它等价于a=0,但它也可以用在数组上,即指定一个长度为零的动态数组或一个相同长度的静态数组,并重置所有元素。对于结构体,它分配一个所有成员重置了的结构体。

>我已经实现了它,通过这个简单的例子可能有助于理解

**

如果我们使用索引删除元素,它将不会留下空白。

**

http://solidity.readthedocs.io/en/v0.4.21/types.html

contract UserRecord {
    constructor() public { owner = msg.sender; }

    address owner;

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    struct User {
        bytes32 userEmail;
        uint index;
    }

    mapping (bytes32 => User) private users;

    bytes32[] private usersRecords;
    event LogNewUser(bytes32 indexed userEmail, uint index);

    function setUseremail(bytes32 _userEmail) public onlyOwner returns(bool success){
        users[_userEmail].userEmail = _userEmail;
        users[_userEmail].index = usersRecords.push(_userEmail) -1;

        emit LogNewUser(
        _userEmail,
        users[_userEmail].index
        );
        return true;
    }

//this will delete the user at particular index and gap will be not there

    function deleteUser(bytes32 _userEmail) public onlyOwner returns(uint index){
        require(!isUser(_userEmail)); 
        uint toDelete = users[_userEmail].index;
        bytes32 lastIndex = usersRecords[usersRecords.length-1];
        usersRecords[toDelete] = lastIndex;
        users[lastIndex].index = toDelete; 
        usersRecords.length--;
        return toDelete;   
    }    
}
||
||

回答发布于 2018-09-11 21:25:13
pragma solidity ^0.4.11;
contract TestArray {
    uint[] public original;
    uint[] public newOr;
    event Log(uint n, uint a, uint b, uint c);

    function TestArray(){
        original.push(1);
        original.push(2);
        original.push(3);
        original.push(4);

    }

    function test(){
        newOr = remove(original, 1);
        Log(newOr.length, newOr[0], newOr[1], newOr[2]);
    }
    function remove(uint[] array, uint index) internal returns(uint[] value) {
        if (index >= array.length) return;

        uint[] memory arrayNew = new uint[](array.length-1);
        for (uint i = 0; i<arrayNew.length; i++){
            if(i != index && i<index){
                arrayNew[i] = array[i];
            } else {
                arrayNew[i] = array[i+1];
            }
        }
        delete array;
        return arrayNew;
    }

}
||
||

回答发布于 2018-09-11 21:25:14

对Tjaden Hess回答的一点优化:

contract Test {
    uint[] array = [1,2,3,4,5];
    function remove(uint index)  returns(uint[]) {
        if (index >= array.length) return;

        for (uint i = index; i<array.length-1; i++){
            array[i] = array[i+1];
        }
        array.length--;
        return array;
    }
}

我删除了在array.length--;之前的行delete array[array.length-1];。这减少了函数5000gas的消耗。当数组长度减少时,编译器会自动清理未占用的空间。双重存储重置可以增加5000gas。

||
||

回答发布于 2018-09-11 21:25:15

使用delete运算符删除元素:

delete array[index];

如果你不想留下间隙,那就需要手动移动每个元素:

contract test{
    uint[] array = [1,2,3,4,5];
    function remove(uint index)  returns(uint[]) {
        if (index >= array.length) return;

        for (uint i = index; i<array.length-1; i++){
            array[i] = array[i+1];
        }
        delete array[array.length-1];
        array.length--;
        return array;
    }
}

如果你不关心顺序,也可以把最后一个元素复制到空出来的地方,然后删除最后一个元素。

||
||

回答发布于 2018-09-11 21:25:15

使用delete运算符删除元素:

delete array[index];

如果你不想留下间隙,那就需要手动移动每个元素:

contract test{
    uint[] array = [1,2,3,4,5];
    function remove(uint index)  returns(uint[]) {
        if (index >= array.length) return;

        for (uint i = index; i<array.length-1; i++){
            array[i] = array[i+1];
        }
        delete array[array.length-1];
        array.length--;
        return array;
    }
}

如果你不关心顺序,也可以把最后一个元素复制到空出来的地方,然后删除最后一个元素。

||
||

回答发布于 2018-09-11 21:25:14

对Tjaden Hess回答的一点优化:

contract Test {
    uint[] array = [1,2,3,4,5];
    function remove(uint index)  returns(uint[]) {
        if (index >= array.length) return;

        for (uint i = index; i<array.length-1; i++){
            array[i] = array[i+1];
        }
        array.length--;
        return array;
    }
}

我删除了在array.length--;之前的行delete array[array.length-1];。这减少了函数5000gas的消耗。当数组长度减少时,编译器会自动清理未占用的空间。双重存储重置可以增加5000gas。

||
||

回答发布于 2018-09-11 21:25:13
pragma solidity ^0.4.11;
contract TestArray {
    uint[] public original;
    uint[] public newOr;
    event Log(uint n, uint a, uint b, uint c);

    function TestArray(){
        original.push(1);
        original.push(2);
        original.push(3);
        original.push(4);

    }

    function test(){
        newOr = remove(original, 1);
        Log(newOr.length, newOr[0], newOr[1], newOr[2]);
    }
    function remove(uint[] array, uint index) internal returns(uint[] value) {
        if (index >= array.length) return;

        uint[] memory arrayNew = new uint[](array.length-1);
        for (uint i = 0; i<arrayNew.length; i++){
            if(i != index && i<index){
                arrayNew[i] = array[i];
            } else {
                arrayNew[i] = array[i+1];
            }
        }
        delete array;
        return arrayNew;
    }

}
||
||

回答发布于 2018-09-11 21:25:12

删除a是把类型的初始值赋给a,也就是说对于整数,它等价于a=0,但它也可以用在数组上,即指定一个长度为零的动态数组或一个相同长度的静态数组,并重置所有元素。对于结构体,它分配一个所有成员重置了的结构体。

>我已经实现了它,通过这个简单的例子可能有助于理解

**

如果我们使用索引删除元素,它将不会留下空白。

**

http://solidity.readthedocs.io/en/v0.4.21/types.html

contract UserRecord {
    constructor() public { owner = msg.sender; }

    address owner;

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    struct User {
        bytes32 userEmail;
        uint index;
    }

    mapping (bytes32 => User) private users;

    bytes32[] private usersRecords;
    event LogNewUser(bytes32 indexed userEmail, uint index);

    function setUseremail(bytes32 _userEmail) public onlyOwner returns(bool success){
        users[_userEmail].userEmail = _userEmail;
        users[_userEmail].index = usersRecords.push(_userEmail) -1;

        emit LogNewUser(
        _userEmail,
        users[_userEmail].index
        );
        return true;
    }

//this will delete the user at particular index and gap will be not there

    function deleteUser(bytes32 _userEmail) public onlyOwner returns(uint index){
        require(!isUser(_userEmail)); 
        uint toDelete = users[_userEmail].index;
        bytes32 lastIndex = usersRecords[usersRecords.length-1];
        usersRecords[toDelete] = lastIndex;
        users[lastIndex].index = toDelete; 
        usersRecords.length--;
        return toDelete;   
    }    
}
||
||