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 on 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, numbers, …, numbers to represent individual variables.
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.
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.
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 = ‘new value’;, we also can also get a particular array element position by simple using myArray where 0 is the index or key of the array element
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 type where the unit must be the variable type again and the number of elements that will be in the array in the bracket ().
To add value to the memory array, we cannot use the .push() method, as we need to use the index notation instead like newArray = 1 , newArray = 1 etc. We can read a value, update a value, delete a value from the memory array just like the storage array.
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:
 555  123 ...  22  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;
mapping(int => bool) mapName;
We can manipulate a map within a function like below:
We can assign an array as a value type to a map and can access them as we would an array like below:
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: