You can simply do:
function deletePayoutYield() {
delete payout.yield;
}
Or in a array:
function deletePayoutYield(uint index) {
delete payoutArray[index].yield;
}
function deletePayout(uint index) {
delete payoutArray[index];
}
You may want a linked list.
Removing an element and then shifting all the others over is the best way to deal with this using an array. (BTW, I'm pretty sure that's how JavaScript's splice
works, too.) Using a linked list would allow you to efficiently remove an element.
That said, do you also need to insert elements and preserve sorted order? If so, how are you doing the insert? (That also sounds like an O(n) operation.) You could consider other data structures, like a heap or a balanced tree, or you could sort on-demand on the client. It all depends on what your scenario is.
EDIT
In response to the question edit, this is fine, but think about the expected ratio of deleted items to existing items. If, after much use, you have 10 items with 10,000 deleted items in between them, you'll find this is extremely inefficient. A linked list doesn't have this problem.
Also consider using exists = true
instead of deleted = false
. This may save gas depending on the expected use.
EDIT 2
A hastily-thrown-together doubly linked list implementation. Please test before using. :-)
pragma solidity ^0.4.21;
contract DoublyLinkedList {
struct Node {
bytes payload;
uint256 next;
uint256 prev;
}
uint256 nextNodeID = 1; // 0 is a sentinel value.
mapping(uint256 => Node) nodes;
uint256 head;
uint256 tail;
uint256 count = 0;
function append(bytes payload) public {
if (tail == 0) {
// 0 is a sentinel. tail == 0 means head == 0 and the list is empty.
head = nextNodeID;
tail = nextNodeID;
nodes[nextNodeID].payload = payload;
} else {
nodes[tail].next = nextNodeID;
nodes[nextNodeID].payload = payload;
nodes[nextNodeID].prev = tail;
tail = nextNodeID;
}
nextNodeID += 1;
count += 1;
}
function validNode(uint256 nodeID) internal view returns (bool) {
return nodeID == head || nodes[nodeID].prev != 0;
}
function remove(uint256 nodeID) public {
require(validNode(nodeID));
Node storage node = nodes[nodeID];
// Update head and tail.
if (tail == nodeID) {
tail = nodes[nodeID].prev;
}
if (head == nodeID) {
head = nodes[nodeID].next;
}
// Update previous node's next pointer.
if (node.prev != 0) {
nodes[node.prev].next = node.next;
}
// Update next node's previous pointer.
if (node.next != 0) {
nodes[node.next].prev = node.prev;
}
// Reclaim storage for the removed node.
delete nodes[nodeID];
count -= 1;
}
function getNodeIDs() public view returns (uint256[] ids) {
ids = new uint256[](count);
uint256 current = head;
for (uint256 i = 0; i < count; i++) {
ids[i] = current;
current = nodes[current].next;
}
}
function getPayload(uint256 nodeID) public view returns (bytes) {
require(validNode(nodeID));
return nodes[nodeID].payload;
}
}
Best Answer
You simply have to loop over the values to find the one you are searching for.
Something like this: