# map

The `map` module offers a versatile toolkit for manipulating collections of
key-value pairs, enabling advanced data operations within a graph database
context.

| Trait               | Value               |
| ------------------- | ------------------- |
| **Module type**     | util                |
| **Implementation**  | C++                 |
| **Graph direction** | directed/undirected |
| **Edge weights**    | weighted/unweighted |
| **Parallelism**     | sequential          |

## Functions

### `remove_key()`

The procedure removes the specified key and its corresponding value from the
input map. If the key does not exist in the input map, it will be ignored.
Additionally, when the recursive config is enabled, the key will also be removed
from any inner maps that are part of the input map.

#### Input:

- `map: Map` ➡ The map from which the key will be removed (a node or relationship may be passed; its properties are used).
- `key: string` ➡ The key to be removed from the map.
- `config: Map default = {recursive: false}` ➡ The config map which supports the
`recursive` option. The option `recursive` is `false` by default, and should be
set to `true` if the input map consists of values that are also maps and,
therefore, may have the key to be removed. If anything other than `false` or
`true` is placed as a value for `recursive`, it is as if `false` was placed. 

#### Output:

- `Map` ➡ the map after removing the specified key.

#### Usage:

The following query will remove the `c: "b"` key-value pair from the map:

```cypher
RETURN map.remove_key({c: "b", d: "ba"}, "c") AS map_without_c;
```

```plaintext
+----------------------------+
| map_without_c              |
+----------------------------+
| {"d": "ba"}                |
+----------------------------+
```

The following query will remove the `c: "b"`, `c: "h"` and `c: "z"` key-value pairs from
the main map and submap due to the `recursive` option set to `true`:

```cypher
RETURN map.remove_key({c: "b", d: {e: "ba", c: "h", a: {c: "z"}}}, "c",{recursive: true}) AS removed;
```

```plaintext
+----------------------------+
| map_without_c              |
+----------------------------+
| {"d": {"e": "ba"}}         |
+----------------------------+
```

### `remove_keys()`

The following procedure removes keys from the input map. If recursive option is
set to `true`, it will remove keys from maps nested inside the map. 

> **Info**
>
> This function is equivalent to **apoc.map.removeKeys**.

#### Input:

- `map: Map[Any]` ➡ The input map (a node or relationship may be passed; its properties are used).
- `keys: List[string]` ➡ A list of keys that will be removed.
- `config: Map default = {recursive: false}` ➡ A config map which supports the
`recursive` option. The `recursive` option is `false` by default, and should be
set to `true` if the input map consists of values that are also maps and,
therefore, may have the key to be removed. 

#### Output:

- `Map[Any]` ➡ The resulting map.

#### Usage:

The following query will remove the `key: 1` pair.

```cypher
RETURN map.remove_keys({key: 1, key2:{key: 3, key3: 5}},["key"]) AS result;
```

```plaintext
+----------------------------------------+
| result                                 |
+----------------------------------------+
|{"key2": {"key": 3,"key3": 5}}          |
+----------------------------------------+
```

The following query will remove the `key: 1` and `key: 3` pair because te
`recursive` options is set to `true`.

```cypher
RETURN map.remove_keys({key: 1, key2:{key: 3, key3: 5}},["key"],{recursive: true}) AS result;
```

```plaintext
+----------------------------------------+
| result                                 |
+----------------------------------------+
|{"key2": {"key3": 5}}                   |
+----------------------------------------+
```

### `from_pairs()`

The procedure creates a map from a list of pairs, where each pair is essentially
another list of size 2. The first element in each pair must be of type `string`,
as it will be used as a key in the resulting map.

#### Input:

- `pairs: List[List]` ➡ The list of pairs.

#### Output:

- `Map` ➡ A map in which the keys are the first elements in the pairs, and the
  corresponding values are the second elements in the pairs.

#### Usage:

The following query will create a map from a list:

```cypher
RETURN map.from_pairs([["b", 3], ["c", "c"]]) AS map;
```

```plaintext
+----------------------------+
| map                        |
+----------------------------+
| {"b": 3, "c": "c"}         |
+----------------------------+
```

### `merge()`

The procedure merges two maps into one. If the same key occurs twice, the later
value will overwrite the previous one. 

If null is provided as an argument, it will resolve to an empty map.

> **Info**
>
> This function is equivalent to **apoc.map.merge**.

#### Input:

- `map1: mgp.Nullable[Map]` ➡ The first map to merge (a node or relationship may be passed; its properties are used).
- `map2: mgp.Nullable[Map]` ➡ The second map to merge. On a key conflict, its value takes precedence.

#### Output:

- `Map` ➡ The merged input maps.

#### Usage:

The following query will merge maps:

```cypher
RETURN map.merge({a: "b", c: "d"}, {e: "f", g: "h"}) AS merged;
```

```plaintext
+----------------------------------------+
| merged                                 |
+----------------------------------------+
| {a: "b", c: "d", e: "f", g: "h"}       |
+----------------------------------------+
```

### `merge_list()`

Merges a list of maps into a single map. Keys are merged left to right, so when
the same key appears in more than one map, the value from the last map wins. An
empty list yields an empty map.

> **Info**
>
> This function is equivalent to **apoc.map.mergeList**.

#### Input:

- `maps: List[Map]` ➡ The maps to merge (each element may be a node or relationship, whose properties are used).

#### Output:

- `Map` ➡ The merged map.

#### Usage:

The following query merges a list of maps:

```cypher
RETURN map.merge_list([{a: 1}, {a: 2, b: 3}]) AS merged;
```

```plaintext
+----------------------------------------+
| merged                                 |
+----------------------------------------+
| {a: 2, b: 3}                           |
+----------------------------------------+
```

### `flatten()`

The procedure flattens nested items in the input map.

#### Input:

- `map: Map[Any]` ➡ The input map that needs to be modified (a node or relationship may be passed; its properties are used).
- `delimiter: string (default = ".")` ➡ The delimiter used for flattening.

#### Output:

- `Map[Any]` ➡ The flattened map, sorted alphabetically by keys.

#### Usage:

The following query will flatten the contents of the map:

```cypher
RETURN map.flatten({a: {b:3, d:4}},"/") AS result;
```

```plaintext
+----------------------------------------+
| result                                 |
+----------------------------------------+
| {"a/b": 3, "a/d": 4}                   |
+----------------------------------------+
```

### `from_lists()`

The procedure makes a map from lists of keys and corresponding values.

> **Info**
>
> This function is equivalent to **apoc.map.fromLists**.

#### Input:

- `keys: List[string]` ➡ A list of keys.
- `values` ➡ A list of values.

#### Output:

- `Map[Any]` ➡ The resulting map.

#### Usage:

The following query will create a map from two lists:

```cypher
RETURN map.from_lists(["key","key2"],[1,2]) AS result;
```

```plaintext
+----------------------------------------+
| result                                 |
+----------------------------------------+
| {""key": 1, "key2": 2}                 |
+----------------------------------------+
```

### `from_values()`

Returns a map from the given list of values. The list has the format: `[key1,
value1, key2, value2]`. Keys are converted to strings; a pair whose key is
`null` is skipped (its value is ignored).

> **Info**
>
> This function is equivalent to **apoc.map.fromValues**.

#### Input:

- `values: List[Any]` ➡ A list of values.

#### Output:

- `Map` ➡ The resulting map.

#### Usage:

The following query will create a map from a list of values:

```cypher
RETURN map.from_values(["day", "sunny", 5, 6]) AS map;
```

```plaintext
+----------------------------------------+
|        map                             |
+----------------------------------------+
| {"5": 6, "day": "sunny"}               |
+----------------------------------------+
```

### `set_key()`

Updates the value at the position `key` in a map. If the key doesn't exist,
the function will insert it. A `null` map is treated as empty and a `null` key
is a no-op (the map is returned unchanged).

> **Info**
>
> This function is equivalent to **apoc.map.setKey**.

#### Input:

- `map: mgp.Nullable[Map]` ➡ The map that will be modified (a node or relationship may be passed; its properties are used).
- `key: mgp.Nullable[string]` ➡ The key to add or update; a `null` key leaves the map unchanged.
- `value: mgp.Nullable[Any]` ➡ The new value of the key-value pair.

#### Output:

- `Map` ➡ The modified map.

#### Usage:

The following query will replace the value of the key `name`:

```cypher
RETURN map.set_key({name:"Ivan",country:"Croatia"}, "name", "Matija") AS map;
```

```plaintext
+-------------------------------------------+
|                     map                   |
+-------------------------------------------+
| {"country": "Croatia", "name": "Matija"}  |
+-------------------------------------------+
```

### `get()`

Returns the value stored under `key` in the map. If the key is absent, the
function returns `value` when it is non-null; otherwise it throws when `fail` is
`true` (the default) or returns `null` when `fail` is `false`. An existing key
always wins, even when its stored value is `null`.

> **Info**
>
> This function is equivalent to **apoc.map.get**.

#### Input:

- `map: Map` ➡ The map to look up (a node or relationship may be passed; its properties are used).
- `key: string` ➡ The key to look up.
- `value: any (default = null)` ➡ The value returned when the key is absent.
- `fail: boolean (default = true)` ➡ When `true`, throws if the key is absent and `value` is null; when `false`, returns `null` instead.

#### Output:

- `any` ➡ The value at `key`, the fallback `value`, or `null`.

#### Usage:

The following query returns the fallback value because the key is absent:

```cypher
RETURN map.get({name: "Ivan"}, "country", "unknown", false) AS value;
```

```plaintext
+----------------------------------------+
| value                                  |
+----------------------------------------+
| "unknown"                              |
+----------------------------------------+
```

## Procedures

### `from_nodes()`

Returns a map of all nodes that contain the given label and property. The key
of each map element will be the value of the property (if it is convertible to a
string, otherwise the procedure throws `ValueException`).

#### Input:

- `subgraph: Graph` (**OPTIONAL**) ➡ A specific subgraph, which is an [object of type Graph](https://memgraph.com/docs/advanced-algorithms/run-algorithms#run-procedures-on-subgraph) returned by the `project()` function, on which the algorithm is run. 
If subgraph is not specified, the algorithm is computed on the entire graph by default.
- `label: string` ➡ The searched label.
- `property: string` ➡ The searched property.

#### Output:

- `result: Map` ➡ The map containing all the matching nodes, their labels and properties.

#### Usage:

```cypher
CREATE (Oppenheimer:Movie {title:'Oppenheimer', released:2023});
CREATE (Barbie:Movie {title:"Barbie", released:2023});
CREATE (Shawshank:Movie {title:'The Shawshank Redemption', released:1994});

CALL map.from_nodes("Movie", "title") YIELD map RETURN map;
```

```plaintext
{
   "Barbie": {
      "identity": 53,
      "labels": [
         "Movie"
      ],
      "properties": {
         "released": 2023,
         "title": "Barbie"
      }
   },
   "Oppenheimer": {
      "identity": 52,
      "labels": [
         "Movie"
      ],
      "properties": {
         "released": 2023,
         "title": "Oppenheimer"
      }
   },
   "The Shawshank Redemption": {
      "identity": 54,
      "labels": [
         "Movie"
      ],
      "properties": {
         "released": 1994,
         "title": "The Shawshank Redemption"
      }
   }
}
```
