我正在使用Sass(v3.3.0.alpha.392),我有一个看起来有点像这样的多维列表,
$list: (
config: (
foo: (
a: 1,
b: 2,
),
bar: (
a: 3,
b: 4,
),
));
我有一个带参数的@mixin,如果它存在于config $列表中,它将根据传递的参数输出。像这样的东西,
@mixin foo($arg) {
@if $arg exists in $list == true { // is 'foo' or 'bar'
// Do something
} @else {
@warn "failed.";
}
}
用法,
.test {
@include foo(bar); // should return true and run code block
@include foo(data); // should return false and @warn
}
但是,我找不到正确的函数来检查$ list中是否存在$ arg。我尝试过检查索引的小函数,
@function exists($n) {
@return (false == index($list, config $n));
}
但是,这似乎不起作用(我可能只是错误地使用它)。我基本上需要根据arg是否包含在$ list中来切换不同的操作。
此外,可能是一个双重问题,但是还有什么方法可以检查$ arg是整数还是字符串?也会非常有帮助。
谢谢!
答案 0 :(得分:4)
您的$list
实际上是地图:
type-of($list) == map
如果我理解正确,您有兴趣将密钥与值匹配(例如bar
)
有一个名为map-has-key($map, $key)
的函数,如果找到匹配的键,则返回true,但在多维映射中,它只匹配最顶层的键。但是,您可以编写一个简单的包装函数,以递归方式将map-has-key
应用于地图的所有级别,直到找到匹配项。包装函数可以是这样的:
@function rmhk($m, $a){
@if map-has-key($m, $a) { @return true; };
@each $key,$e in $m {
@if (type-of($e) == map) and rmhk($e, $a) { @return true; }
}
@return false;
}
以相同的方式(使用递归函数)除了键之外还可以匹配地图中的值或遍历列表而不是地图(DEMO在多维列表中具有值匹配)。
而且,正如@Jeremy已经指出的那样,您可以使用type-of()
来检查变量的类型(例如string
,number
,list
,{ {1}},map
),但如果由于某种原因你需要检查更具体的东西,你需要一个自定义函数(例如,这个短函数用于检查值是否为整数:{{3 }})。
答案 1 :(得分:1)
你可以像第二个问题那样使用type-of:
@if type-of($arg) == number {
...
}
对于第一个问题,您无法访问具有非数字索引的列表,因此,您的帮助程序索引($ list,config $ n)会中断。我不知道你为什么使用多维列表,sass并不是真的为它而建,并没有真正的需要。在正常列表中使用
@if index($list, $arg) != false {
...
}
会很好,我的建议是进入并重构你的代码所以它不需要2d列表,但如果你必须那么你必须你必须迭代每个级别上的每个项目来检查$ arg如果有意义,则存在于每个“列表中的列表”中......
所以你会得到(我的sass有点生疏我不知道@each是否是列表中的迭代函数)
@each $list in lists {
@if type-of($list) == list {
@if index($list, $arg) != false {
...
}
}
@else {
go deeper
}
}
这很难看,让它以任何方式运行都会成为一个问题。你要做的是以一种不是的方式使用Sass,你试图使sass列表像javascript对象一样,它们是非常不同的。您应该只考虑使用新的map functions作为键值,这实际上就是你需要做的任何事情(事实上,将地图作为地图中的值是javascript对象是什么,你可以这样做)