# mergeAll

Let's forget about observable for now, and revisit the data structure we use everyday: Array.

say, I have an array,

`[1, 2, 3] // these are just numbers wrapped in a context, and this context happens to be Array.`

and I can use `map`

to transform the element into another element, for example I can multiple each element by 2

```
[1, 2, 3].map((x) => 2 * x)
// [2, 4, 6], so we have new numbers still in the context: Array
```

I can chain other methods on this context too, as these methods will be evaluated on the elements in the context

```
[1, 2, 3]
.map((x) => 2 * x)
.filter((x) => x > 4)
```

Here's the interesting part, what if the returned value is another context (another array)

```
[1, 2, 3].map((x) => [2 * x])
// [[2], [4], [3]]
```

Can I still chain `filter`

after this `map`

?

```
[1, 2, 3].map((x) => [2 * x])
.filter((x) => x > 4) // what is x here?
```

The `x`

here is actually the element which is another element in context(Array), aka, Higher Order Array(or Nested Array).

in order to use following chaining methods on the context, we need to extract the element inside the nested brackets. Javascript happens to have a method called flat to do this job

```
[1, 2, 3]
.map((x) => [2 * x])
.flat()
// [2, 4, 3]
```

And we can happily to `filter`

again!

```
[1, 2, 3]
.map((x) => [2 * x])
.flat()
.filter((x) => x > 4)
```

If you understand what `flat`

does in Array, then you alredy knows the role of `mergeAll`

.

In the context of Observable, we have a method called `mergeAll`

equivalent to `flat`

in the context of Array.
It is usually used togher with `map`

, where here `map`

returns a new context(new Observable)

```
of(1, 2, 3).pipe(
map((x) => of(2 * x)), // returns a new Observable
mergeAll(),
filter((x) => x > 4)
)
```

And since `map`

+ `mergeAll`

is a so common combination, we have mergeMap to simplify operators.