-- Shakespeare, Henry IV Part I
Act III, Scene I, Line 5.1
Mapcat is an interesting higher order function which is not talked about much.
"You've never danced like this before
We don't talk about it"
-- Milky Chance,
Stolen Dance
The simplest case of Mapcat is when you have a collection of collection and you want to map over the collection of collection yielding a single level of collection.
In the image above we see that we have a collection of two collections (top and bottom) and a function which maps and cats (mapper catter) when these are Mapcatted that yield a result which is a single collection. The size of the result from the Mapcat is the size of the collection's collections, in the image above we see that we have 4 members of the first collection and 2 members in the second collection giving us the resulting collection with 6 members.
The simplest example of Mapcat would be using the identity function (a function which just returns whatever is given to it).
We see that collection which contains a collection we 1, 2, 3, and 4 and another collection with 20 and 10 when Mapcatted with the Identity function will yield a resulting collection with 1, 2, 3, 4, 20, and 10.
We see in C# we can use the SelectMany to perform this simple Mapcat, while Clojure has a function called mapcat.
This is nice but how about a simple example which actual does something?
How about incrementing the values?
We see that in both C# and Clojure the lambda in the Mapcat is given a collection, so in both cases we need to have a function which can work with a collection. We have a choice in both C# and Clojure we can either have a Map in the lambda or we can chain the result by removing a level with the identity function follow by a simple Map with an incrementing lambda function. In Clojure we can do chaining using the double arrow macro (thread last) ->> or just nest the calls.
The simplest case of Mapcat is when you have a collection of collection and you want to map over the collection of collection yielding a single level of collection.
In the image above we see that we have a collection of two collections (top and bottom) and a function which maps and cats (mapper catter) when these are Mapcatted that yield a result which is a single collection. The size of the result from the Mapcat is the size of the collection's collections, in the image above we see that we have 4 members of the first collection and 2 members in the second collection giving us the resulting collection with 6 members.
The simplest example of Mapcat would be using the identity function (a function which just returns whatever is given to it).
We see that collection which contains a collection we 1, 2, 3, and 4 and another collection with 20 and 10 when Mapcatted with the Identity function will yield a resulting collection with 1, 2, 3, 4, 20, and 10.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(mapcat identity [[1 2 3 4] [20 10]]) | |
;;(1 2 3 4 20 10) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
new[] { | |
new[] {1, 2, 3, 4}, | |
new[] {20, 10} | |
}.SelectMany(x => x); | |
// { 1, 2, 3, 4, 20, 10 } |
We see in C# we can use the SelectMany to perform this simple Mapcat, while Clojure has a function called mapcat.
This is nice but how about a simple example which actual does something?
How about incrementing the values?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(mapcat #(map inc %) [[1 2 3 4] [20 10]]) | |
;; (2 3 4 5 21 11) | |
(map inc | |
(mapcat identity [[1 2 3 4] [20 10]])) | |
;;(2 3 4 5 21 11) | |
(->> | |
[[1 2 3 4] [20 10]] | |
(mapcat identity) | |
(map inc)) | |
;;(2 3 4 5 21 11) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
new[] { | |
new[] {1, 2, 3, 4}, | |
new[] {20, 10} | |
}.SelectMany(x => x.Select(a => a + 1)); | |
// { 2, 3, 4, 5, 21, 11 } | |
csharp> new[] { | |
new[] {1, 2, 3, 4}, | |
new[] {20, 10} | |
}.SelectMany(x => x).Select(x => x + 1); | |
//{ 2, 3, 4, 5, 21, 11 } |
We see that in both C# and Clojure the lambda in the Mapcat is given a collection, so in both cases we need to have a function which can work with a collection. We have a choice in both C# and Clojure we can either have a Map in the lambda or we can chain the result by removing a level with the identity function follow by a simple Map with an incrementing lambda function. In Clojure we can do chaining using the double arrow macro (thread last) ->> or just nest the calls.