Is there a pop functionality for solidity arrays?

前端 未结 3 1084
失恋的感觉
失恋的感觉 2021-02-20 10:36

I have used solidity to push data into an array. Is there a similar function for pop ?

string[] myArray;
myArray.push(\"hello\")

What is the be

相关标签:
3条回答
  • 2021-02-20 11:11

    Yes there is, as of v0.5.0 (details here):

    Dynamic storage arrays and bytes (not string) have a member function called pop that you can use to remove an element from the end of the array. This also implicitly calls :ref:delete on the removed element.

    0 讨论(0)
  • 2021-02-20 11:17

    Update 2-19-2019: As Joel pointed out below, pop has been added to built-in array support. See https://solidity.readthedocs.io/en/v0.5.4/types.html#array-members. Leaving original answer on here in case others are using older versions of Solidity.


    There is no pop function in Solidity. You have a few options you can consider for maintaining your array.

    Delete & Leave Gaps

    The simplest solution is to just delete the element at a specific index:

    string element = myArray[index];
    delete myArray[index];
    return element;
    

    However, this will NOT shift the elements in your array and will leave an element of "string 0" in your array. To check this element, you would use

    if(bytes(myArray[index]).length > 0) ...

    Swap & Delete

    If you don't care about order in your array, you can swap the element with the last element in your array and then delete:

    string element = myArray[index];
    myArray[index] = myArray[myArray.length - 1];
    delete myArray[myArray.length - 1];
    myArray.length--;
    return element;
    

    Delete With Shift

    If order in your array is important, you can delete the element then shift all remaining elements to the left.

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

    Note that this will be the most expensive of the options. If your array is very long, you will have high gas usage.

    Correlating with @Jedsada's suggestion, here is a version as a library:

    pragma solidity ^0.4.24;
    
    library StackLib {
      using StackLib for Stack;
    
      struct Stack {
        uint[] _items;
      }
    
      function pushElement(Stack storage self, uint element) internal returns (bool) {
        self._items.push(element);
      }
    
      function popElement(Stack storage self) internal returns (uint) {
        uint element = self.peek();
    
        if (self.size() > 0)
          delete self._items[self.size() - 1];
    
        return element;
      }
    
      function peek(Stack storage self) internal returns (uint) {
        uint value;
    
        if (self.size() > 0)
          value = self._items[self.size() - 1];
    
        return value;
      }
    
      function size(Stack storage self) internal returns (uint8) {
        return self.size();
      }
    }
    

    Example usage (Important note: You can't use popElement and return the value to a client. That method changes state and should only be used within a transaction.):

    contract Test {
      using StackLib for StackLib.Stack;
    
      StackLib.Stack numbers;
    
      function add(uint v) public {
        numbers.pushElement(v);
      }
    
      function doSomething() public {
        for (uint8 i = 0; i < numbers.size(); i++) {
          uint curNum = numbers.popElement();
    
          // do something with curNum
        }
      }
    }
    

    Additional note: Unfortunately, var has been deprecated since 0.4.20 and there is no replacement for generics. You have to customize for a specific type.

    0 讨论(0)
  • 2021-02-20 11:28

    You can try...

    pragma solidity ^0.4.17;
    
    contract TestArray {
       uint[] public items;
    
       constructor () public {
          items.push(1);
          items.push(2);
          items.push(3);
          items.push(4);
       }
    
       function pushElement(uint value) public {
          items.push(value);
       }
    
       function popElement() public returns (uint []){
          delete items[items.length-1];
          items.length--;
          return items;
       }
    
       function getArrayLength() public view returns (uint) {
          return items.length;
       }
    
       function getFirstElement() public view returns (uint) {
          return items[0];
       }
    
       function getAllElement()  public view returns (uint[]) {
          return items;
       }
    }
    
    0 讨论(0)
提交回复
热议问题