This content originally appeared on Kitty Giraudel and was authored by Kitty Giraudel
I have this article ready for about 3 months now but I never found an occasion to release it… until today! This will be quite short but I still wanted to write a little something on the topic anyway. You might have read my article about SassyCast, a small Compass extension I wrote to convert data types in Sass.
SassyCast making possible to go from any data type to any data type (or almost), it includes a way to cast a map into a list. While the function I wrote was kind of straight forward, Julien Cabanes showed me a cool little improvement to the function on Twitter. I merged his code in SassyCast 1.0.0.
The old way
The to-list
function core is pretty straightforward. If the given value is a map, we iterate over it to create a 2-dimensional list like this: ( "key-1" "value 1", "key-2" "value 20" )
.
@function to-list($value) {
@if type-of($value) == 'map' {
$keys: ();
$values: ();
@each $key, $val in $value {
$keys: append($keys, $key);
$values: append($values, $val);
}
@return zip($keys, $values);
}
@return if(type-of($value) != 'list', ($value,), $value);
}
To be a little more precise about what’s being done here: we loop through each map entry, store the key in a $keys
list and the value in a $values
list. Then we zip both to return a 2-dimensional list where the first element of each list if the former key and the second element of each list is the former value.
Does the job well.
The new way
Julien thought it would be cool to be able to keep only keys, or only values or both (what I’ve done) so he added an extra parameter to the function accepting either keys
or values
or both
. Every other value would fallback to both
.
Then depending on the flag, he returns either $keys
or $values
or a zip of both.
@function to-list($value, $keep: 'both') {
$keep: if(index('keys' 'values', $keep), $keep, 'both');
@if type-of($value) == 'map' {
$keys: ();
$values: ();
@each $key, $val in $value {
$keys: append($keys, $key);
$values: append($values, $val);
}
@if $keep == 'keys' {
@return $keys;
} @else if $keep == 'values' {
@return $values;
} @else {
@return zip($keys, $values);
}
}
@return if(type-of($value) != 'list', ($value,), $value);
}
If you don’t like conditional return statements or if you simply want to look like a badass with an unreadable ternary mess, you could return something like this:
@return if($keep == 'keys', $keys, if($keep == 'values', $values, zip($keys, $values)));
Literally:
- If
$keep
is'keys'
, return$keys
- Else if
$keep
is'values'
, return$values
- Else return
zip($keys, $values)
Final thoughts
Let’s try it with a little example, shall we? First, our map.
$breakpoints: (
'small': 600px,
'medium': 900px,
'large': 1200px
);
And now, we cast it to a list.
$breakpoints-list: to-list($breakpoints, 'both');
// ('small' 600px, 'medium' 900px, 'large' 1200px)
$breakpoints-keys: to-list($breakpoints, 'keys');
// ('small' 'medium' 'large')
$breakpoints-values: to-list($breakpoints, 'values');
// (600px 900px 1200px)
That’s all folks! Thanks again Julien!
This content originally appeared on Kitty Giraudel and was authored by Kitty Giraudel
Kitty Giraudel | Sciencx (2014-04-28T00:00:00+00:00) Casting a map into a list in Sass. Retrieved from https://www.scien.cx/2014/04/28/casting-a-map-into-a-list-in-sass-2/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.