Array
Array бол нэг төрлийн утгуудыг дараалсан байдлаар хадгалах өгөгдлийн бүтэц. Solidity-д array хоёр хэлбэртэй — тогтмол урт (fixed-size) ба динамик урт (dynamic).
Fixed-size array — тогтмол урт
Урт нь урьдчилан тодорхойлогдсон, өөрчлөгдөхгүй array:
uint256[5] public scores; // яг 5 элемент
address[3] public winners; // яг 3 элемент
bool[10] public slots; // яг 10 элемент
Зарлах үед бүх элемент default утга авна — uint256 бол 0, bool бол false, address бол address(0).
contract FixedArray {
uint256[3] public rgb;
function setColor(uint256 r, uint256 g, uint256 b) public {
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
}
function getRed() public view returns (uint256) {
return rgb[0];
}
}
Хил хэтэрсэн index ашиглахад runtime revert гарна:
uint256[3] arr;
arr[5] = 1; // ❌ index out of bounds → revert
Dynamic array — динамик урт
Урт нь өсч буурдаг array. Storage-д зарлахад хэмжээний хязгааргүй:
uint256[] public numbers;
address[] public members;
string[] public names;
push — элемент нэмэх
contract DynamicArray {
uint256[] public numbers;
function addNumber(uint256 n) public {
numbers.push(n); // array-ийн төгсгөлд нэмнэ
}
function getLength() public view returns (uint256) {
return numbers.length;
}
function getLast() public view returns (uint256) {
require(numbers.length > 0, "Array хоосон байна");
return numbers[numbers.length - 1];
}
}
pop — сүүлийн элемент хасах
function removeLast() public {
require(numbers.length > 0, "Array хоосон байна");
numbers.pop(); // сүүлийн элементийг устгана, length-г нэгээр багасгана
}
pop нь хасагдсан утгыг буцааж өгдөггүй — устгахаас өмнө хадгалах шаардлагатай бол:
function popAndReturn() public returns (uint256 last) {
last = numbers[numbers.length - 1]; // эхлэж хадгална
numbers.pop(); // дараа нь устгана
}
Array iterate хийх
contract Scores {
uint256[] public scores;
function addScore(uint256 s) public { scores.push(s); }
function getTotal() public view returns (uint256 total) {
for (uint256 i = 0; i < scores.length; i++) {
total += scores[i];
}
}
function getAverage() public view returns (uint256) {
require(scores.length > 0, "Оноо байхгүй");
return getTotal() / scores.length;
}
function findMax() public view returns (uint256 max) {
for (uint256 i = 0; i < scores.length; i++) {
if (scores[i] > max) {
max = scores[i];
}
}
}
}
⚠️ Gas анхааруулга: Array урт ихсэх тусам loop-ийн gas зарцуулалт нэмэгдэнэ. Маш урт array-г бүтнээр нь давтах нь gas limit-г давж revert болох эрсдэлтэй.
Storage vs Memory array
Storage array — blockchain-д байнга хадгалагдана, state variable.
Memory array — функц дотор түр үүснэ, функц дуусмагц устана. Урт нь урьдчилан тодорхойлогдсон байх ёстой.
contract ArrayLocation {
uint256[] public stored; // storage array
function processNumbers(uint256 count) public view returns (uint256[] memory) {
// memory array — тогтмол урттайгаар үүсгэнэ
uint256[] memory result = new uint256[](count);
for (uint256 i = 0; i < count; i++) {
result[i] = (i + 1) * 10;
}
return result; // memory array буцаана
}
}
Memory array-д push/pop ажилладаггүй — зөвхөн index-ээр унших, бичих боломжтой.
Storage-г memory-д хуулах — gas оновчлол
uint256[] public bigArray;
// ❌ storage-г дахин дахин уншина → gas өндөр
function sumExpensive() public view returns (uint256 total) {
for (uint256 i = 0; i < bigArray.length; i++) {
total += bigArray[i]; // SLOAD бүр gas зарцуулна
}
}
// ✅ нэг удаа memory-д хуулна → gas хямд
function sumCheap() public view returns (uint256 total) {
uint256[] memory arr = bigArray; // нэг удаа хуулна
for (uint256 i = 0; i < arr.length; i++) {
total += arr[i];
}
}
Array delete-ийн аюул
delete arr[i] нь элементийг default утга болгодог, array-г богиносгодоггүй:
uint256[] public nums = [10, 20, 30, 40, 50];
delete nums[2];
// nums → [10, 20, 0, 40, 50] — length өөрчлөгдсөнгүй!
// 0 "хоосон цоорхой" болж үлдэнэ
Дунд элементийг зайлуулж array-г нягтруулахын тулд:
// Арга 1: Сүүлийн элементтэй сольж pop хийх (дараалал алдагдана)
function removeAt(uint256 index) public {
require(index < numbers.length, "Буруу index");
numbers[index] = numbers[numbers.length - 1]; // сүүлийнхийг хийнэ
numbers.pop(); // сүүлийнхийг устгана
}
// Арга 2: Дараалал хадгалах (gas өндөр)
function removeAtOrdered(uint256 index) public {
require(index < numbers.length, "Буруу index");
for (uint256 i = index; i < numbers.length - 1; i++) {
numbers[i] = numbers[i + 1]; // зүүн тийш шилжүүлнэ
}
numbers.pop();
}
2D array
uint256[3][3] public grid; // 3×3 тогтмол
uint256[][] public matrix; // динамик
function setCell(uint256 row, uint256 col, uint256 val) public {
grid[row][col] = val;
}
Дараагийн хичээлд:
struct — холбоотой өгөгдлийг нэг нэгжид бүлэглэх, mapping ба array-тай хослуулах аргыг судална.