# Maps

**Maps** are the second kind of *collections* available in Sonar. Similarly to the *dictionary* of Python, the *hash* of Ruby and the *object-map* of JavaScript, **Sonar**'s *map* allows you to store data as a collection of *key-value pairs*. Each value can be retrieved if you know its key, much like a door can be unlocked if you have its key, or your iPhone can be unlocked if you have the right passcode.

More correctly, maps in **Sonar** collections of *key-value pairs*, arranged so that each *key* only appears once. In other words, maps emulate a *one-to-one mapping relationship.*

Maps are most useful when it is necessary to store a collection of values using a value other than their index (or position).

### Maps Work Like Dictionaries

Maps follow the same principle as dictionaries (and thesauri, and all other reference books like catalogues and phonebooks). In fact, using a map, one can write a phonebook pretty easily, as we will see.

Map keys can be strings, numbers (integers and floats), and booleans. These datatypes are called **hashables**. Non-hashable types like arrays and other maps cannot be used as map keys.

### Creating a Map

Creating a map is incredibly easy using the **map operator** (**{}**).

```javascript
>> let my_map = {}
// outputs {}
```

You can create a map with data in it from the beginning:

```javascript
>> let my_new_map = {"name": "Santa Claus", "age": 100}
// outputs {'name': 'Santa Claus', 'age': 100}
```

### Accessing Map Values

Similar to Arrays, we can access specific map values using the **accessor operator**, provided we know the corresponding key.

```javascript
>> my_new_map["name"]
// outputs 'Santa Claus'
>> my_new_map["age"]
// outputs 100
```

Values can also be changed:

```javascript
>> my_new_map["age"] = 200
// outputs 200
>> my_new_map
// outputs {'name': 'Santa Claus', 'age': 200}
```

New keys can be created with values:

```javascript
>> my_new_map["favourite_colour"] = "red"
// outputs {'age': 200, 'name': 'Santa Claus', 'favourite_colour': 'red'}
```

### Removing Keys/Values from Maps

A *key-value pair* can be deleted from a map with the minus (-) operator.

```javascript
>> my_new_map - "age"
// outputs {'name': 'Santa Claus', 'favourite_colour': 'red'}
```

It is important to remember that this operation **will change the original map**. If you need to retain the key in the original map, you will need to make a copy of the map first.

```javascript
>> let my_copied_map = copy(my_new_map)
// outputs {'name': 'Santa Claus', 'favourite_colour': 'red'}

>> my_copied_map - "name"
// outputs {'age': 100}

>> my_new_map
// outputs {'name': 'Santa Claus', 'favourite_colour': 'red'}
```

> **copy()** can be used with every data type.

With all we have learned so far, we can create a phonebook program very easily:

{% code lineNumbers="true" %}

```javascript
let phonebook = {}
func newContact(name, number) {
    phonebook[name] = number
}
func deleteContact(name) {
    phonebook - name
}

newContact("Icheka", 123456789)
print(phonebook)

deleteContact("Icheka")
print(phonebook)

// outputs:
// {'Icheka': 123456789}
// {}
```

{% endcode %}

> Maps are also called "associative arrays". Can you find out why?


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://icheka-ozuru.gitbook.io/sonarlang/syntax-basics/data-structures/maps.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
