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 best solution for this ? How do I delete an element in a dynamic array in solidity ?
4. Pop: Pop is used when the last element of the array is to be removed in any dynamic array. Example: In the below example, the contract Types first initializes an array[data], and then values are removed from the array using the pop function.
In Solidity, an array can be of compile-time fixed size or of dynamic size. For storage array, it can have different types of elements as well.
We can create a function remove() that will take an array's index as an argument. Then the function will set the index argument to the last element in the array. Simply, we will shift the index argument over the last element of the array. Then we will remove the last element by using the pop() method.
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[i] = myArray[i + 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With