是否有固件数组的弹出功能?

时间:2018-03-01 14:29:11

标签: data-structures solidity

我已经使用solidity将数据推送到数组中。 pop有类似的功能吗?

import requests
from bs4 import BeautifulSoup

url = 'http://www.bmfbovespa.com.br/pt_br/servicos/market-data/consultas/mercado-de-derivativos/precos-referenciais/taxas-referenciais-bm-fbovespa/'

r = requests.get(url)
soup = BeautifulSoup(r.text,'lxml')
soup.find_all(id = 'tb_principal1')

最佳解决方案是什么?如何在实体中删除动态数组中的元素?

4 个答案:

答案 0 :(得分:6)

更新2-19-2019 :正如Joel在下面指出的那样,pop已被添加到内置阵列支持中。见https://solidity.readthedocs.io/en/v0.5.4/types.html#array-members。在这里留下原始答案,以防其他人使用旧版本的Solidity。

Solidity中没有弹出功能。您可以考虑使用几个选项来维护阵列。

删除&留下差距

最简单的解决方案是仅delete特定索引处的元素:

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

但是,这不会移动数组中的元素,并且会在数组中留下“string 0”元素。要检查此元素,您可以使用

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

交换&删除

如果您不关心数组中的顺序,可以将元素与数组中的最后一个元素交换,然后删除:

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

按Shift键删除

如果数组中的顺序很重要,则可以删除元素,然后将所有剩余元素移到左侧。

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;

请注意,这将是最昂贵的选项。如果你的阵列很长,你的气体使用量很高。

与@ Jedsada的建议相关,这是一个作为库的版本:

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();
  }
}

示例用法(重要说明:您不能使用popElement并将值返回给客户端。该方法会更改状态,只应在事务中使用。):

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
    }
  }
}

附加说明:不幸的是,var自0.4.20以来已被弃用,并且没有替代泛型。您必须针对特定类型进行自定义。

答案 1 :(得分:1)

您可以尝试...

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;
   }
}

答案 2 :(得分:1)

function deleteElement(uint _index) public returns(bool) {
    if (_index < 0 || _index >= x.length) {
        return false;
    } else if(x.length == 1) {
        x.pop();
        return true;
    } else if (_index == x.length - 1) {
        x.pop();
        return true;
    } else {
        for (uint i = _index; i < x.length - 1; i++) {
            x[i] = x[i + 1];
        }
        
        x.pop();
        return true;
    }
} 

答案 3 :(得分:0)

是的,自v0.5.0(details here)起:

  

动态存储数组和字节(不是字符串)具有一个称为pop的成员函数,可用于从数组末尾删除元素。这也隐式调用了被删除元素上的:ref:delete。