zoukankan      html  css  js  c++  java
  • Solidity遍历

      实际上,映射对于存储地址的标记值非常有用。 我们在许多合约中都看到了它们,它们通常以这种方式定义:

    mapping (address => uint) public users;

      由于映射是公共的,我们得到一个免费的getter,我们可以通过使用简单的方法获取myAddress的值

    users(myAddress);

      Solidity映射看起来可能类似于关联数组,但它不是,它没有索引,因此很难遍历所有地址。但它仍然可以通过其它方法遍历。

      数组更容易管理:

    address[] public addressIndices;
    // start adding address in array
    addressIndices.push(newAddress);
    ...
    // We know the length of the array
    uint arrayLength = addressIndices.length;
    for (uint i=0; i<arrayLength; i++) {
      // do something
    }

      假设我们想要计算所有地址的总值,拥有一组地址确实很有帮助。

    mapping (address => uint) public mappedUsers;
    address[] public addressIndices;
    // start adding address in array
    addressIndices.push(newAddress);
    // define mappedUsers as well
    mappedUsers[newAddress] = someValue;
    ...
    // We know the length of the array
    uint arrayLength = addressIndices.length;
    // totalValue auto init to 0
    uint totalValue;
    for (uint i=0; i<arrayLength; i++) {
      totalValue += mappedUsers[addressIndices[i]];
    }

      如果我们想要有效地删除数组怎么办? 我们必须将数组的最后位置移动到已删除的位置。

    uint indexToBeDeleted;
    mapping (address => uint) public mappedUsers;
    address[] public addressIndices;
    uint arrayLength = addressIndices.length;
    for (uint i=0; i<arrayLength; i++) {
      if (addressIndices[i] == addressToBeDeleted) {
        indexToBeDeleted = i;
        break;
      }
    }
    // if index to be deleted is not the last index, swap position.
    if (indexToBeDeleted < arrayLength-1) {
      mappedUsers[indexToBeDeleted] = mappedUsers[arrayLength-1];
    }
    // we can now reduce the array length by 1
    addressIndices--;

      参考上面的代码,假设我们不希望for循环查找要删除的地址的索引,我们需要在结构中记录项的索引。 如果我们想要做一个合适的CRUD,它会变得有点复杂。

      完整代码的示例参考如下:

    pragma solidity^0.4.17;
    
    contract Test {
        
        struct structUser {
            uint value;
            uint index;
            bool exists;
        }
    
        mapping(address => structUser) public arrayStructs;
        
        address[] public addressIndexes;
        
        function addAddress(uint _val) public returns (bool){
            // if user exists, add _val
            if (arrayStructs[msg.sender].exists > true) {
                arrayStructs[msg.sender].value += _val;
            }
            else {
                // else its new user
                addressIndexes.push(msg.sender);
                arrayStructs[msg.sender].value = _val;
                arrayStructs[msg.sender].index = addressIndexes.length-1;
                arrayStructs[msg.sender].exists = true;
            }
            return true;
        }
        
        function deleteAddress() public returns (bool) {
            // if address exists
            if (arrayStructs[msg.sender].exists) {
                structUser memory deletedUser = arrayStructs[msg.sender];
                // if index is not the last entry
                if (deletedUser.index != addressIndexes.length-1) {
                    // delete addressIndexes[deletedUser.index];
                    // last strucUser
                    address lastAddress = addressIndexes[addressIndexes.length-1];
                    addressIndexes[deletedUser.index] = lastAddress;
                    arrayStructs[lastAddress].index = deletedUser.index; 
                }
                delete arrayStructs[msg.sender];
                addressIndexes.length--;
                return true;
            }
        }
        
        function getAddresses() public view returns (address[]){
            return addressIndexes;    
        }
        
        function getTotalValue() public view returns (uint) {
            uint arrayLength = addressIndexes.length;
            uint total = 0;
            for (uint i=0; i<arrayLength; i++) {
                total += arrayStructs[addressIndexes[i]].value;
            }
            return total;
        }
        
        function getTotalUsers() public view returns (uint) {
            return addressIndexes.length;
        }
    }

      代码来源地址:https://github.com/bernardpeh/solidity-loop-addresses-demo/blob/master/loop-demo.sol

    文章来源:https://medium.com/@blockchain101/looping-in-solidity-32c621e05c22

  • 相关阅读:
    【数学】三分法
    【数学】【背包】【NOIP2018】P5020 货币系统
    【数学】【CF27E】 Number With The Given Amount Of Divisors
    【单调队列】【P3957】 跳房子
    【极值问题】【CF33C】 Wonderful Randomized Sum
    【DP】【CF31E】 TV Game
    【神仙题】【CF28D】 Don't fear, DravDe is kind
    【线段树】【CF19D】 Points
    【字符串】KMP字符串匹配
    【二维树状数组】【CF10D】 LCIS
  • 原文地址:https://www.cnblogs.com/flyingeagle/p/10140270.html
Copyright © 2011-2022 走看看