Blockchain/Solidity
delete element of array and mapping - 공부하는 도비
DOVISH WISDOM
2023. 1. 2. 20:30
728x90
반응형
array의 인덱스 번호로 element 삭제 방법
pragma solidity ^0.8.1;
contract Practice {
uint256[] private arr;
function remove(uint256 _index) private {
require(_index < arr.length, "index out of bound");
for (uint i = _index; i < arr.length - 1; i++) {
arr[i] = arr[i + 1];
}
arr.pop();
}
function test() external {
// case_1
arr = [1, 2, 3, 4, 5];
remove(2); // want : arr = [1, 2, 4, 5]
// checking
assert(arr[0] == 1);
assert(arr[1] == 2);
assert(arr[2] == 4);
assert(arr[3] == 5);
assert(arr.length == 4);
// case_2
arr = [1];
remove(0); // want : arr = []
// checking
assert(arr.length == 0);
}
}
mapping의 value리스트 값 삭제하는 방법 (이중 리스트의 값 삭제와 동일)
pragma solidity ^0.8.7;
contract Test {
address public owner;
mapping (uint256 => address) public tokenOwner; // 특정 토큰의 번호를 넣었을 때, 그 토큰의 소유주를 출력
mapping (uint256 => string) public tokenStrs; // 특정 토큰에 적혀있는 Str 출력
mapping (address => uint256[]) private ownedTokens; // 소유한 토큰 리스트 : 주소를 입력하면, 그 주소가 가진 tokenId를 출력력
constructor() public {
owner = msg.sender;
}
// 토큰 발행 함수
function mintWithTokenURI(address to, uint256 tokenId, string memory tokenStr) public {
require(owner == msg.sender);
// to에게 tokenId를 발행
tokenOwner[tokenId] = to;
tokenStrs[tokenId] = tokenStr;
// add token to the list
ownedTokens[to].push(tokenId);
}
// 토큰 전송 (from address to address sometokenid)
function transferFromTo(address from, address to, uint256 tokenId) public {
require(owner == msg.sender);
require(from == tokenOwner[tokenId], "you are not the owner of the token");
tokenOwner[tokenId] = to;
// from 주소에 해당하는 tokenId를 list에서 삭제해야함
// if문으로 tokenId에 해당하는 index를 얻고, 그 값을 삭제
for(uint256 i = 0; i < ownedTokens[from].length; i++) {
if (ownedTokens[from][i] == tokenId) {
ownedTokens[from][i] = ownedTokens[from][ownedTokens[from].length-1];
ownedTokens[from].pop();
break;
}
}
// 새로운 주소에 add token to the list
ownedTokens[to].push(tokenId);
}
// 소유한 토큰
function PrintOwnedTokens(address some_address) public view returns (uint256[] memory) {
return ownedTokens[some_address];
}
}
이 부분이 삭제에 해당하는 부분입니다.
// from 주소에 해당하는 tokenId를 list에서 삭제해야함
// if문으로 tokenId에 해당하는 index를 얻고, 그 값을 삭제
for(uint256 i = 0; i < ownedTokens[from].length; i++) {
if (ownedTokens[from][i] == tokenId) {
ownedTokens[from][i] = ownedTokens[from][ownedTokens[from].length-1];
ownedTokens[from].pop();
break;
}
}
물론 함수로도 작성이 가능합니다.
//_removeTokenId(from, tokenId);
// private으로 선언
function _removeTokenId(address from, uint256 tokenId) private {
for(uint256 i = 0; i < ownedTokens[from].length; i++) {
if (ownedTokens[from][i] == tokenId) {
ownedTokens[from][i] = ownedTokens[from][ownedTokens[from].length-1];
ownedTokens[from].pop();
break;
}
}
}
솔리디티에서 배열의 값을 삭제하기 위해선 아래 그림과 같은 과정을 거쳐야 합니다.
arr = [10, 40, 5, 8, 20, 15]
40을 삭제하고 싶다면,
40과 배열의 맨 끝 값(15)과 자리를 바꿉니다(swap).
마지막으로 arr.pop()으로 배열의 마지막 값을 삭제(꺼냅니다(pop))합니다.