SCSS:检查多维列表中是否存在值

时间:2014-02-16 21:41:17

标签: sass

我正在使用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是整数还是字符串?也会非常有帮助。

谢谢!

2 个答案:

答案 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

以相同的方式(使用递归函数)除了键之外还可以匹配地图中的值或遍历列表而不是地图(DEMO在多维列表中具有值匹配)。

而且,正如@Jeremy已经指出的那样,您可以使用type-of()来检查变量的类型(例如stringnumberlist,{ {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对象是什么,你可以这样做)