Arrays in Solidity¶
This example demonstrates different types of arrays in Solidity, their usage patterns, and comparison with mappings.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ArrayExamples {
// Fixed-size array
uint[5] public fixedArray;
// Dynamic array
uint[] public dynamicArray;
// Array of strings
string[] public stringArray;
// Memory array (only in functions)
function createMemoryArray(uint size) public pure returns (uint[] memory) {
// Memory arrays must be fixed-size
uint[] memory memoryArray = new uint[](size);
// Fill array with some values
for(uint i = 0; i < size; i++) {
memoryArray[i] = i + 1;
}
return memoryArray;
}
// Array operations
function arrayOperations() public {
// Push: Add to end of array
dynamicArray.push(1);
dynamicArray.push(2);
// Pop: Remove and return last element
if(dynamicArray.length > 0) {
dynamicArray.pop();
}
// Length
uint length = dynamicArray.length;
// Delete: Resets element to default value (0)
// but keeps array length unchanged
if(length > 0) {
delete dynamicArray[0];
}
}
// Array limitations and gas considerations
function arrayLimitations() public {
// Fixed arrays are limited by stack depth (around 16 elements)
uint[3] memory smallArray = [uint(1), 2, 3];
// Dynamic arrays can grow but:
// 1. Push operations cost more gas as size increases
// 2. Iteration becomes expensive with large arrays
// 3. Array length is limited by block gas limit
// Use this array for demonstration
for(uint i = 0; i < smallArray.length; i++) {
dynamicArray.push(smallArray[i]);
}
}
// When to use arrays vs mappings
mapping(uint => uint) public numberMapping;
function arrayVsMapping() public {
// Arrays are better when you need:
// 1. Length/size tracking
// 2. Iteration over elements
// 3. Sequential access
// 4. Push/pop operations
// Mappings are better when you need:
// 1. Random access by key
// 2. Sparse data structures
// 3. Large number of elements
// 4. No need for iteration
// Example: Using mapping
numberMapping[0] = 100;
numberMapping[1] = 200;
// No length property
// No iteration capability
// But very efficient key-based access
}
}
Key Concepts¶
-
Array Types
- Fixed-size arrays:
type[N]
- Dynamic arrays:
type[]
- Memory arrays must be fixed-size
- Fixed-size arrays:
-
Array Operations
- push: Add element to end
- pop: Remove last element
- length: Get array size
- delete: Reset element to default
-
Limitations
- Fixed arrays limited by stack depth
- Dynamic arrays limited by gas costs
- Memory arrays must be fixed-size
- Array length limited by block gas limit
-
Arrays vs Mappings
Arrays better for:
- Sequential access
- Known, limited size
- Need for length tracking
- Iteration requirements
Mappings better for:
- Random access
- Large datasets
- Sparse data structures
- No iteration needed
Best Practices¶
- Use fixed arrays when size is known and small
- Consider mappings for large datasets
- Be cautious with array growth in loops
- Monitor gas costs with large arrays
- Use memory arrays for temporary operations
Array Element Removal Examples¶
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ArrayRemovalExamples {
uint[] public numbers;
// Initialize array for examples
constructor() {
numbers = [1, 2, 3, 4, 5];
}
// Remove last element (most gas efficient)
function removeLastElement() public {
require(numbers.length > 0, "Array is empty");
numbers.pop();
}
// Remove element at specific index by shifting elements
// [1, 2, 3, 4, 5] remove index 2 -> [1, 2, 4, 5]
function removeByShifting(uint _index) public {
require(_index < numbers.length, "Index out of bounds");
for (uint i = _index; i < numbers.length - 1; i++) {
numbers[i] = numbers[i + 1];
}
numbers.pop();
}
// Remove element by copying last element to index
// [1, 2, 3, 4, 5] remove index 2 -> [1, 2, 5, 4]
// Note: This changes array order but is more gas efficient
function removeBySwap(uint _index) public {
require(_index < numbers.length, "Index out of bounds");
// Move last element to the index being removed
numbers[_index] = numbers[numbers.length - 1];
// Remove the last element
numbers.pop();
}
// Get current array (for testing)
function getArray() public view returns (uint[] memory) {
return numbers;
}
}
Key Points About Array Removal¶
-
Pop Last Element
- Most gas efficient method
- Only works when order doesn't matter
- O(1) operation
-
Shift Elements
- Maintains array order
- Gas expensive for large arrays
- O(n) operation
-
Swap and Pop
- Does not maintain order
- Gas efficient
- O(1) operation
Choose the removal method based on your specific needs:
- Use
pop()
when removing from the end - Use shift when order must be maintained
- Use swap-and-pop when order doesn't matter and gas efficiency is important