Sass maps: A better function for retrieving values
The @each
directive in Sass is used to loop through a map or list. This post gives an example of how we can use this to get values from nested maps.
The original method
In my previous post How to use Sass maps, I gave an example with nested maps and a function to retrieve the values from them. Here's the function.
@function socialSet($set, $key){
@return map-get(map-get($social, $set), $key);
}
We call map-get
twice to allow us the retrieve the nested values. This works perfectly fine but feels a bit clunky. It is also quite brittle, the function can only be used for a nested map one level deep. Should we wish to change the structure of our map, it could break our Sass.
A better way
I happened to come across this Stack Overflow question about iterating nested maps. The solution uses the @each
directive to iterate through the map. This feels like a nicer, more elegant approach so let's apply it to our example.
Instead of calling map-get
on map-get
we can use @each
to do the work for us. Lets consider this example.
$map: $social; // the name of our map
@each $key in twitter, colour {
$map: map-get($map, $key);
}
Our keys to iterate are twitter, colour
. We initially set $map
to the name of the map we want to use, in this case $social
. With each iteration $map
is set to the value returned from map-get
. That value is then used as the map parameter for the next iteration. In the last iteration $map
is set to the value we wish to retrieve.
Here's the final function.
@function mapGet($map, $list...) {
@each $key in $list {
$map: map-get($map, $key);
}
@return $map; // Our value
}
// usage
.smokey {
color: mapGet(social, twitter, colour);
}
// outputs
.smokey {
background-color: #eee;
}
If you wondered what $list...
is, it is a variable argument this allows a function/mixin to take a variable number of arguments (our list to loop through).
Summary
By using @each
to loop through a set of keys, we are able to produce a generic function to retrieve values from maps of any structure whether they are nested or not. A definite improvement on the original function!