Arrays and Maps in Solidity
By: Agoi Abel
Tags: Solidity, Ethereum, Beginner, Blockchain Development, Blockchain

An array allows us to represent a collection of data, but it is often more useful to think of an array as a collection of variables of the same type with keys having sequential order based off the order they were added.

Instead of declaring individual variables, such as number1, number2, number3, ….., and number99, you can declare one array variable such as numbers and use numbers[0], numbers[1], …, numbers[99] to represent individual variables.

Having understood how the array works in JAVASCRIPT and PHP, I was going to rush through it in solidity but to my greatest surprise, it is quite different here in the solidity blockchain world :). I decided to write about the array and map since both of them seem similar to me and can be used together.

Unlike in javascript where we could have an array of integer together with strings or any other data type, our array must have the variable of the same data type and this can be enforced when declaring it like below:

uint[] myArray; //declaring an array of integer variables

Before I dive fully into the array in solidity, I want to clarify that there are two types of arrays in solidity, which are the storage array and the memory array.

Storage Array:

These are arrays that are stored inside the blockchain after you execute your function, you can declare them like normal variables without our contract like below:

where unit/bool/address is the variable type, followed by [] and then the name of the array which can be any name.

Manipulation of the storage array:

To add a new element to the array, we need to reference the array and use the .push(value), we can also update an array position by referencing the element key like myArray[0] = ‘new value’; , we also can also get a particular array element position by simple using myArray[0] where 0 is the index or key of the array element

We can also use the for loop to access the element of the array as we would array in javascript (also in the snippet above). To delete an element in the array, we will use delete myArray[1] where 1 is the array key, please note that this will not affect the array length but will only reset the array value at the index of one or second element in the array to the default value of the data type. i.e 0 if it’s a uint type and false if bool. When we try to access an array key that does not exist, we will have an error.

Memory Array:

These arrays are not stored into the blockchain after calling the function, you can only declare them within a function like below:

where unit[] is the type of the variables, memory keyword declares it has a memory array followed by the name which can be an acceptable name, it must be equated to new unit[](10) type where the unit[] must be the variable type again and the number of elements that will be in the array in the bracket () .

Manipulation of the memory array:

To add value to the memory array, we cannot use the .push() method, as we need to use the index notation instead like newArray[0] = 1 , newArray[1] = 1 etc. We can read a value, update a value, delete a value from the memory array just like the storage array.

Passing an array as a function argument:

We can pass an array as a function argument in solidity, the function visibility determines if the keyword before the array name should be calldata or memory . We use calldata if the function visibility is external and memory if the function visibility is public and internal. See example below:

Seems we have covered all we need to do in an array, how about mapping .

A Map is something like an array with a collection of similar variables that uses key look-ups meaning you’re referencing values with an object instead of an integer in short.

Basically, mapping is equivalent to a dictionary or a map in other programming languages. It’s key-to-value storage. A standard array is an index look-up e.g. if there are 10 elements in the array the indexes are 0–9 and it would look like below as an array of integers:

[0] 555

[1] 123

...

[8] 22

[9] 5

The map works slightly different and the easiest way to describe it is that it uses key lookups. So if this was a map of addresses to integers then it would look something like:

[0x000000000000000A] 555

[0x0000000000000004] 123

....

[0x0000000000000006] 22

[0x0000000000000003] 6

So basically, you’re referencing values with an object instead of an integer. The keys also don’t have to be in sequence. It consists of two main parts: a _KeyType and a _ValueType ; they appear in the following syntax below:

mapping (_KeyType => _ValueType) mapName .

Think of the _KeyType as the key you'll pass through a function to return the desired value, or _ValueType . By default, a mapping is initially empty, so a new _KeyType will first need to be mapped to a _ValueType .

It could be

mapping(string => string) mapName;

Or

mapping(int => bool) mapName;

Manipulation of a map:

We can manipulate a map within a function like below:

We assigned a value to the map here balances[msg.sender] = 100 by equating it to a value. We read the value also by balances[msg.sender] without assigning any value. When we use a non-existence key to read a value from a map, it will return the default data value used to initialize the value type when declaring it unlike undefined in javascript.

Assign an array as a map value:

We can assign an array as a value type to a map and can access them as we would an array like below:

Assign another map as a map value:

We can also assign another map as a map value and can access them as we would access a map like below:

We can assign a Struct as a map value type too, there are occasions when you want to iterate over a map and do other things on a map, I would advise you check out the resources below when the need arises:

If you got this far, you are cute, thank you for reading.