Welcome back to series about SASS/SCSS. If you like this topic, this is a link for you follow other articles. Series about SASS/SCSS
In this
article, we will continue to discuss about built-in modules, specifically
sass:map.
For a more
general and accurate view of this article, I have an article about Maps in
SASS/SCSS. You can find out more here. Maps in SASS/SCSS
Table of
contents:
- Overview
- Functions in Built-in Modules Maps
Let’s go to
the content!
Overview
We have Maps
consisting of key/value pairs. Sometimes in some cases, Maps is not simply
key/value pairs, but it is also Nested Maps, which means Maps in Maps in
Maps...
If we handle
Maps with key/value pairs, we can simply process it through the get() and set()
functions without having to import any additional libraries to be able to use
them..
When the
problem becomes more complicated than Maps in Maps in Maps…, we need a library
to be able to handle this problem. Sass has built for us a Built-in Modules
that is sass:map. Let's go into the functions to learn how to use it.
Functions
in Built-in Module Maps
Map.deep-merge($map1,
$map2)
When reading
the function name is deep-merge, can you imagine what this function will be
used for? That is, merge $map1 and $map2 together. However, the difference is
deep-merge. To understand better, we will look at the following example, and we
will compare it with the merge() function.:
// index.scss
@use 'sass:map';
$map1: (
"child-map": (
"primary": 1,
"secondary": 2
));
$map2: (
"child-map": (
"accent": 3,
"highlight": 4
));
@debug map.deep-merge($map1, $map2);
// =>
("child-map":("accent": 3, "highlight": 4,
"primary": 1, "secondary": 2))
@debug map-merge($map1: $map1, $map2: $map2);
// => ("child-map":
("accent": 3, "highlight": 4))
First, we
have two Maps, $map1 and $map2. Both are Nested Maps. We will use the
deep-merge() function which is a function in the library of “sass:map” to merge
two Maps together. You can see the result is a new Maps, this Maps will contain
all the results of both Maps together.
Next, we use
the map-merge() function which is a function written in Sass global. You can
see completely different result with function deep-merge() the value of $map2
completely overrides the value of $map1.
So, through
the above example we can see how deep-merge and map-merge work. Depending on
the purpose of use, you can choose the function accordingly.
Map.deep-remove($map,
$key, $keys…)
In Sass
global we have a built-in function map-remove. In the module “sass:map” we have
a function that is deep-remove. This function also has the function of deleting
the key/value pair based on the $key we give. At the same time, we can delete
multiple key/value pairs at the same time. Besides, if $map is a Nested Maps,
we need to have an argument of $keys, so that we can specify which $key we need
to remove..
// index.scss
@use 'sass:map';
$map1: ("child-map": ("primary": 1,
"secondary": 2));
@debug map.deep-remove($map1, "primary");
// => ("child-map": ("primary":
1, "secondary": 2))
@debug map.deep-remove($map1, "child-map", "primary");
// => ("child-map":
("secondary": 2))
@debug $map1;
// => ("child-map":
("primary": 1, "secondary": 2))
You can see
it in the example above. We have a Nested Map, if we use the argument $key that
$key is deep inside, then our function will not delete this key/value pair. We
need to specify which $key is in the $key, the return result will be $map with
that $key removed.
Another
caveat is that map.deep-remove() will only make a copy of the original $map.
The results will be saved in this copy. The original $map will not be affected.
Map.get($map,
$key, $keys…) – map-get($map, $key, $keys…)
In a task
where we want to get the value of key/value pair via $key in a given $map. We
will use the map.get() function, or we can replace it with map-get(). With the
$keys argument we will handle in the case of Nested Maps, the $keys are inside
$key.
// index.scss
@use 'sass:map';
$map1: (
"child-map": (
"primary": 1,
"secondary": 2
));
@debug map.get($map1, "child-map", "primary"); // => 1
@debug map.get($map1, "child-map", "accent"); // => null
If we determine
the correct $key we can get the result we want completely. In other cases, if
you enter the wrong $key, the return result will be null.
So, there
will be a question, that these functions require you to remember the exact
order and name of the $key to be able to get the value of that $key. If in an
extremely large $map this is not feasible at all. Currently the only way we
have that is to manually define $key. The Sass engine does not yet support
this. If you want a solution, you can refer to JavaScript, TypeScript, etc. Or
if you have a way to solve the above problem, please comment below so that
everyone like me can learn more from the experience. test.
There is a
fun fact about map.get(), if you have a Map that includes Maps with only one
key/value pair. Sass engine will assist you in extracting the value that lies
deep within that Map.
// index.scss
@use 'sass:map';
$map1: ((1: (2: (3 : 4))));
@debug map.get($map1, 1, 2, 3); // => 4
Map.has-key($map,
$key, $keys…)
If you are
familiar with map.get(), the function map.has-key() does the same thing with
getting $keys or $keys deep inside $map. The return result of function
map.has-key() is Booleans. This means that the function map.has-key() will
check if there is a $key in that $map or not?
// index.scss
@use 'sass:map';
$map1: ((1: (2: (3 : 4))));
@debug map.has-key($map1, 1, 2, 3); // => true
@debug map.has-key($map1, 3); // => false
If you go
through the layers in $map one by one, you will get true. If you immediately
put in that $key you will get false result.
Map.keys($map)
– map.keys($map)
Fucntion
map.keys() will return a List of keys in the first layer in $map.
// index.scss
@use 'sass:map';
$map1: ((1: (2: (3 : 4))));
$map2: (1: 1, 2: 2, 3: 3, 4: 4);
@debug map.keys($map1); // => (1,)
@debug map.keys($map2); // 1, 2, 3, 4
You can see
that, $map1 is a Nested Map, the result is only (1,) the key in the first
layer. $map2 is a regular Map, the return result will be all the keys in the
first layer.
Map.merge($map1,
$map2) – map-merge($map1, $map2)
Map.merge($map1,
$key…, $map2) – map-merge($map1, $key…, $map2)
The
map.merge() function has two ways to use it. The first is map.merge() which
takes two arguments $map1 and $map2.
// index.scss
@use 'sass:map';
$map1: (1: 1, 2: 2);
$map2: (3: 3, 4: 4);
@debug map.merge($map1, $map2); // => (1: 1, 2: 2, 3: 3, 4: 4)
This is the
usual usage for a regular map. The result is a new map containing all the
values of $map1 and $map2. These are 2 regular maps, if we apply the
map-merge() function to the nested map, let's see what the result will be.?
// index.scss
@use 'sass:map';
$map1: (1:
(2: (
3: 3,
4: 4
)),
);
$map2: (5:
(6: (
7: 7,
8: 8
)));
@debug map.merge($map1, $map2);
/** => (1:
(2:
(3: 3, 4: 4)),
5:
(6:
(7: 7, 8: 8)))
*/
The results
of both maps are merged.
You can see
that we can merge two regular maps together, or we can merge two nested maps
together. Now in another case, we have a nested map and another map. We don't
want to merge two maps in the usual way. We want to merge $map2 in a $key of
$map1. Now we will use the following:
// index.scss
@use 'sass:map';
$map1: (1: (2: (3: 3)));
$map2: (4: 4, 5: 5);
@debug map.merge($map1, 1, 2, $map2);
// (
// 1: (
// "2": (
// "3": 3,
// "4": 4,
// "5": 5
// )
// )
// )
In another
case, if the key we set does not exist, the result is that the Sass engine will
create a new map that includes the key we set.
// index.scss
@use 'sass:map';
$map1: (1: (2: (3: 3)));
$map2: (4: 4, 5: 5);
@debug map.merge($map1, 1, 4, $map2);
// (
// 1: (
// "2": (
// "3": 3,
// )
// 4: (
// 4: 4,
// 5: 5,
// )
// )
So you have
covered all the cases where map.merge() can be used.
Map.remove($map,
$keys…) – map-remove($map, $keys…)
Fucntion
map.remove() will return a copy of $map that will delete the key/value pair we
want to delete. We can remove multiple key/value pairs at the same time in
regular maps.
// index.scss
@use 'sass:map';
$map1: (1: 1, 2: 2, 3: 3);
@debug map.remove($map1, 1, 2); // (3: 3)
In the nested
map we are completely different, we cannot delete the key/value pair() deep
inside.
@use 'sass:map';
$map1: (
1: (
2: 2,
3: (
4: 4,
5: 5
)
)
);
@debug map.remove($map1, 1, 2, 3, 4); // ()
Map.set($map,
$key, $value) – map.set($map, $keys…, $key, $value)
If you
understand the usage of the map.get() function, the map.set() function also
works similarly. If you work with regular maps you just need to point the
correct $key and reset $value for that $key.
// index.scss
@use 'sass:map';
$map1: (1: 1, 2: 2, 3: 3);
@debug map.set($map1, 3, 4);
// => (1: 1, 2: 2, 3: 4)
The return
result is a copy of map of the original $map.
In other
case when you work with nested map, you want to change the value of $key deep
inside we can use:
// index.scss
@use 'sass:map';
$map1: (
1: (
2: 2,
3: 3
));
@debug map.set($map1, 1, 2, 9);
// => (
// 1: (
// 2: 9,
// 3: 3
// ))
Map.values($map)
– map-values($map)
The return
result will be a list of the values contained in that $map.
// index.scss
@use 'sass:map';
$map1: (1: 1, 2: 2, 3: 3);
@debug map.values($map1); // 1, 2, 3
Here is the
result for the regular map. And for nested map, what will be the result??
// index.scss
@use 'sass:map';
$map1: (
1: (
2: 2,
3: 3
));
@debug map.values($map1); // ((2: 2, 3: 3),)
We also get
a list of values that $key has.
Conclusion
You have
learned about all the functions included in the built-in modules sass:map. You
can apply this fucntions to a regular map or a nested map depending on the
specific case.
If you have
any ideas, feel free to comment bellow. Thank you for joining with me. Having a
good day!
0 Nhận xét