Arrays

Solidity 0.4.26 檢查元素是否已存在於數組中

  • March 22, 2021

我該如何做到這一點,如果它不存在,這只會給 dataArray 添加一個標識符?

pragma experimental ABIEncoderV2;

contract structWithMapping{

   struct Data{
       string[] user;
       string[] catagory;
       string[]  data;
   }

   mapping(string => Data) mappedData;
   string[] public dataArray;

   function setUserData(string _user, string _catagory, string _data)public{
       var addData = mappedData[_user];

       addData.user.push(_user);
       addData.catagory.push(_catagory);
       addData.data.push(_data);

       dataArray.push(_user) -1;
   }

   function getUsers() view public returns(string[]){
       return dataArray;
   }

   function getUserData(string _user) view public returns(string[] memory, string[] memory, string[] memory){
       return(mappedData[_user].user, mappedData[_user].catagory, mappedData[_user].data);
   }
}

為了避免 For 循環,您可以添加另一個映射來檢查使用者是否存在。您可以添加mapping(string => bool) userExists;,以便您的整個程式碼如下所示:

pragma experimental ABIEncoderV2;


contract structWithMapping{

   struct Data{
       string[] user;
       string[] catagory;
       string[] data;
   }


   mapping(string => Data) mappedData;
   mapping(string => bool) userExists;

   string[] public dataArray;

   function setUserData(string _user, string _catagory, string _data)public{
       var addData = mappedData[_user];


       addData.user.push(_user);
       addData.catagory.push(_catagory);
       addData.data.push(_data);

       require(!userExists[_user]);
       dataArray.push(_user) -1;
       //dont forget to set the mapping value to true for userExists
       userExists[_user] = true;
   }

   function getUsers() view public returns(string[]){
       return dataArray;
   }

   function getUserData(string _user) view public returns(string[] memory, string[] memory, string[] memory){
       return(mappedData[_user].user, mappedData[_user].catagory, mappedData[_user].data);
   }
}

閱讀您的程式碼,我想我了解您想要實現的目標,但我建議完全改變方法。請注意,使用智能合約需要花錢,因此作為開發人員,您的目標應該是創建乾淨的業務邏輯 - 因此它不會被誤解或誤導 - 並且很輕 - 因此每筆交易的成本都盡可能低。

要實現這一點,您還需要深入研究EVMSolidityVyper

也就是說,我認為你的整個智能合約應該變成這樣:

contract structWithMapping {

   struct User {
       string  username;
       string  category;
       string  data;
       bool    initialized;
   }
   mapping(string => User) public users;

   function setUserData(string memory _username, string memory _category, string memory _data) public{
       require(!users[_username].initialized);
       users[_username].username = _username;
       users[_username].category = _category;
       users[_username].data = _data;
       users[_username].initialized = true;
   }

}

另請注意,Solidity 在編譯時為每個公共變數添加了 getter 函式,因此在這種情況下users將創建一個函式。getUserData您可以使用該函式將使用者名作為參數傳遞,以與呼叫函式完全相同的方式檢索使用者數據。

我創建了一個要點,因此您可以通過此連結直接通過 Remix IDE 進行試驗。

引用自:https://ethereum.stackexchange.com/questions/84109