如何有条件地遍历结构映射并且仅 return 一些结构 - Solidity

How to conditionally iterate through a mapping of structs and only return some structs - Solidity

我正在通过编写合同来存储和检索患者病历来学习可靠性。有谁知道为什么函数“getRecordByAddressMap”和“getRecordByAddressStruct”不起作用?他们编译,但事务恢复。

逻辑非常简单,函数遍历映射(或数组),检查地址是否匹配,将结构添加到数组,然后 returns 该数组。

我在这里错过了什么?

contract PatientRecords{
  uint256 public recordID = 1;
  mapping (uint256 => mapping (address => Records)) records;

  struct Records {
      address patient;
      address hospital;
      uint256 admissionDate;
      uint256 dischargeDate;
      uint256 visitReason;
  }

  Records[] recordsarray;
  Records[] getstructs;

  constructor() {
      addRecord(0x3719dB98b075Ff10886Fc29431Ffc2006fFF0005, 
        0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, 20220320, 20220330, 1);
      addRecord(0x3719dB98b075Ff10886Fc29431Ffc2006fFF0005, 
        0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, 20220333, 20220333, 2);
      addRecord(0x60814DB6b62fE178d7F91239078e3c20fB857E04, 
        0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, 20220310, 20220311, 3);
  }

// Add a record to the mapping
  function addRecord (
    address _patientAddress,
    address _hospital,
    uint256 _admissionDate,
    uint256 _dischargeDate,
    uint256 _visitReason)
    public
  {
      records[recordID][_patientAddress].patient = _patientAddress;
      records[recordID][_patientAddress].hospital = _hospital;
      records[recordID][_patientAddress].admissionDate = _admissionDate;
      records[recordID][_patientAddress].dischargeDate = _dischargeDate;
      records[recordID][_patientAddress].visitReason = _visitReason;

      recordsarray.push(Records(_patientAddress, _hospital, _admissionDate, _dischargeDate, _visitReason));
      recordID++;
  }

// Retrieve a record by the patient address and record ID (count)
  function getRecordByID(address _patientAddress, uint256 _recordID) public view returns(Records memory) {
    return records[_recordID][_patientAddress];
  }

// Retrieve a record by the patient address (Mapping method)
  function getRecordByAddressMap(address _patientAddress) public view returns (Records[] memory){
    Records[] memory rec = new Records[](recordID);
      for (uint i = 1; i < recordID; i++) {
        if (_patientAddress == records[i][_patientAddress].patient == true) {
          rec[i] = records[i][_patientAddress];
          } else {
            continue;
          }
      }
    return rec;
  }

    // Retrieve a record by the patient address (Struct method)
  function getRecordByAddressStruct(address _patientAddress) public returns(Records[] memory) {
    Records[] storage _getstructs = getstructs;
    for (uint i = 1; i < recordID; i++) {
      if (_patientAddress == recordsarray[i].patient == true) {
        Records memory newRecord = Records({
          patient: recordsarray[i].patient,
          hospital: recordsarray[i].hospital,
          admissionDate: recordsarray[i].admissionDate,
          dischargeDate: recordsarray[i].dischargeDate,
          visitReason: recordsarray[i].visitReason
        });
        _getstructs.push(newRecord);
        } else {
          continue;
        }
    }
    return _getstructs;
  }

}

当您使用 for 关键字进行迭代时,您不使用记录 ID 而是尝试使用 [array].lenght。 在您的情况下,在 getRecordByAddressMap 函数中以这种方式更改它:

// Retrieve a record by the patient address (Mapping method)
  function getRecordByAddressMap(address _patientAddress) public view returns (Records[] memory){
    Records[] memory rec = new Records[](recordID);
      for (uint i = 1; i <= rec.length; i++) {
        if (_patientAddress == records[i][_patientAddress].patient == true) {
          rec[i] = records[i][_patientAddress];
          } else {
            continue;
          }
      }
    return rec;
  }

并在 getRecordByAddressStruct 函数中将其更改为:

  // Retrieve a record by the patient address (Struct method)
  function getRecordByAddressStruct(address _patientAddress) public returns(Records[] memory) {
    Records[] storage _getstructs = getstructs;
    for (uint i = 1; i < _getstructs.length; i++) {
      if (_patientAddress == recordsarray[i].patient == true) {
        Records memory newRecord = Records({
          patient: recordsarray[i].patient,
          hospital: recordsarray[i].hospital,
          admissionDate: recordsarray[i].admissionDate,
          dischargeDate: recordsarray[i].dischargeDate,
          visitReason: recordsarray[i].visitReason
        });
        _getstructs.push(newRecord);
        } else {
          continue;
        }
    }
    return _getstructs;
  }