BlockChain/솔리디티
Array Remove
정신이 많이없는 개발자
2022. 3. 22. 21:52
728x90
반응형
💡 오늘은 저번 post에 이어서 배열을 삭제하는 방법에 대해서 공부한 내용을 정리해 보려고합니다.
잠깐 저번시간에 작성한 solidity 코드를 자세히 보면 delete라는 부분이 있었습니다.
[1,2,3] 이렇게 작성되어있는 코드에 delete[0]을 하게 되면 [0,2,3] 이런식으로 변경됩니다. 즉 배열을 삭제하고 길이을 줄이는 것이 아니라 해당되는 index의 값을 default값(solidity에서 uint의 default값은 0입니다.)으로 변경해줍니다.
이번 post에서는 [1,2,3] => [2,3] 이렇게 공간자체를 삭제하는 방법에 대해서 기록해보겠습니다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract ArrayShift {
uint[] public arr;
function example() public {
arr = [1,2,3];
delete arr[1]; // [1,0,3]
}
// [1,2,3] -> remove(1) -> [1,3,3] ->[1, 3]
// 결국 배열에서 요소를 삭제하기 위해서는 배열요소를 왼쪽으로 이동한 다음 마지막 요소를 제거합니다.
// remove array element by shifting elements to left;
function remove(uint _index) public {
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 {
arr = [1,2,3,4,5];
remove(2); //[1,2,4,5];
assert(arr[0]==1);
assert(arr[1]==2);
assert(arr[2]==4);
assert(arr[3]==5);
assert(arr.length == 4);
}
}
// [1,2,3,4] --> remove(1) --> [1,4,3];
// [1,4,3] --> remove(2) --> [1, 4];
// gas비를 좀더 절약할 수 있다.
contract ArrayReplaceLast{
uint[] public arr;
function remove(uint _index) public {
arr[_index] = arr[arr.length-1];
arr.pop();
}
function test() external {
arr = [1,2,3,4];
remove(1);
assert(arr[0]==1);
assert(arr[1]==4);
assert(arr[2]==3);
}
function output() external view returns(uint[] memory){
return arr;
}
}
위의 solidity코드를 보게되면 간단하게 2가지 방식이 있습니다.
첫 번째 방식은 제거하려는 index를 기준으로 반복문을 통해서 모든값을 다 변경해준 다음 마지막값을 삭제하는 방식입니다.
ex) [1,2,3,4,5,6,7,8,9,10] => remove(4) => [1,2,3,4,6,7,8,9,10,10] => [1,2,3,4,6,7,8,9,10] 순서로 제거가 됩니다.
두 번째 방식은 제거하려는 index를 배열의 마지막 값으로 대체해준 후 마지막 값을 삭제하는 방식입니다.
ex) [1,2,3,4,5,6,7,8,9,10] => remove(2) => [1,2,10,4,5,6,7,8,9,10] => [1,2,10,4,5,6,7,8,9];
이방식은 gas값은 절약되지만 우리가 원하는대로 값이 정렬이 되지는 않습니다.
블록체인에서 코드에는 값이 매겨지있기 때문에 불필요한 반복은 삼가하는 것이 좋다고 생각이듭니다.
그리고 필요한 배열에서는 최소한으로 줄일 수 있도록 생각을 해봐야 할 것 같습니다.
반응형