如何有条件地遍历结构映射并且仅 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;
}
我正在通过编写合同来存储和检索患者病历来学习可靠性。有谁知道为什么函数“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;
}