5

代替 Chris Eppstein 提到的作为 SASS 正在进行的工作的Map 数据结构之类的东西,我正在尝试实现类似的东西 - 将字符串映射到相应的十六进制值,该值将用于指定 CSS 的 unicode 字符内容属性。(我正在尝试重构一些字体图标 SASS 代码。)

目前我有一些基本的东西,比如:

/*icon1  -->  \F000
  icon2  -->  \F001
  icon3  -->  \F002*/

@function u-char($name) {
    @if $name == icon1 {
        @return "000";
    } @else if $name == icon2 {
        @return "001";
    } @else if $name == icon3 {
        @return "001";
    }
}

@mixin icon-class($name) {
    ...
    content: "\f#{u-char($name)}";
    ...
}

但我实际上是在尝试映射大量字符,所以这种方法很费力。我希望能够做类似的事情:

@function u-char($name) {
    $i: 0;
    $itemList: item1, item2, item3;

    @each $currItem in $itemList {
        @if $name == item1 {
            @return i-to-hex-str($i);
        }
        $i: $i + 1;
    }
}

在 SASS 中有什么可以做整数到十六进制字符串的转换吗?还有另一种优雅的方法吗?

4

5 回答 5

6

要回答您帖子中的最后一个问题,“在 SASS 中是否有任何东西可以将整数转换为十六进制字符串?”。嗯……不是内置的,但我认为这很清楚,而且代码行数相对较少:

/** Returns an at least one byte hex value */
@function dec-to-hex($d) {
    $hexVals: "A" "B" "C" "D" "E" "F";
    $base: 16;
    $quotient: $d;
    $result: "";
    @if $d == 0 {
        $result: "00";
    }
    @while $quotient != 0 {
        $mod: $quotient % $base;
        $quotient: floor($quotient / $base);
        @if $mod > 9 {
            $mod: nth($hexVals, $mod - 9);
        }
        @if $d < $base {
            $result: "0" + $mod;
        } @else {
            $result: $mod + $result;
        }
    }
    @return $result;
}

这不会在字符串前面添加十六进制限定符(例如“0x”或“#”),但您可以将其硬编码到最后一行 ( @return "#" + $result;),或者在调用函数时将其应用在原地。

于 2013-11-01T05:00:10.020 回答
2

您帖子中最后一个问题的另一个实现:“在 SASS 中是否有任何东西可以将整数转换为十六进制字符串?” 这是一个最短的版本(不适用于最旧的版本,因为可能缺少 str-slice)。

@function decToHex($dec) {
    $hex: "0123456789ABCDEF";
    $first: (($dec - $dec % 16)/16)+1;
    $second: ($dec % 16)+1;
    @return str-slice($hex, $first, $first) + str-slice($hex, $second, $second)
}
于 2015-11-27T15:10:00.653 回答
2

前面的答案对我们不起作用,所以这里有两个快速函数用于将整数转换为多个不同的基数,包括十六进制:

@function decimal-to-base($decimal, $to_base, $chars: '0123456789abcdefghijklmnopqrstuvwxyz')
  @if type-of($decimal) != 'number'
    @error '$decimal must be an integer.'
  @if type-of($to_base) != 'number'
    @error '$to-base must be an integer.'
  @if type-of($chars) != 'string'
    @error '$chars must be a string.'
  @if $to_base < 2
    @error '$to-base must be larger than 1.'
  @if $to_base > str-length($chars)
    @error 'Length of $chars must be equal or larger than $to-base.'
  @return _decimal-to-base($decimal, $to_base, $chars)

@function _decimal-to-base($decimal, $to_base, $chars, $_accum: '')
  @if $decimal <= 0
    @return if($_accum != '', $_accum, '0')
  $remainder: $decimal % $to_base
  $char: str-slice($chars, $remainder + 1, $remainder + 1)
  $remaining_decimal: ($decimal - $remainder) / $to_base
  @return _decimal-to-base($remaining_decimal, $to_base, $chars, $char + $_accum)

如果您不关心错误处理,您可以跳过长的第一个函数(它实际上只验证参数并设置默认字符)并复制第二个函数。

另外,请注意这是用 SASS 编写的,而不是 SCSS。对于 SCSS 支持,您需要添加一些花括号和分号。

例子:

  • 十进制转十六进制:
    decimal-to-base(15731618, 16) // "f00ba2".

  • 十进制转二进制:
    decimal-to-base(34, 2) // "100010".

  • 查询字符串的时间戳:
    decimal-to-base(1547598870, 2) // "pleb0y".

  • 绝对不是摩尔斯电码:
    decimal-to-base(34, 2, '-.') // "-...-.".

  • 过度设计的整数到字符串:
    decimal-to-base(123456, 10) // "123456".

已知警告:(因为这是一个肮脏的实现)

  • 输入小数必须是整数 >= 0。
  • 最小基数为 2。
  • 您需要小心处理大整数。
于 2019-01-16T00:35:23.250 回答
2

我在十六进制和十进制数之间来回更改数字的功能是

$hex-chars: "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F";

@function dec-to-hex($d) {
    $result: "";
    $rest: $d;
    @while $rest > 0 {
        $result: nth($hex-chars, $rest % 16 + 1) + $result;
        $rest: floor($rest / 16);
    }
    @return $result;
}

@function pow($number, $exponent) {
    $value: 1;
    @if $exponent > 0 {
        @for $i from 1 through $exponent {
            $value: $value * $number;
        }
    }
    @return $value;
}

@function hex-to-dec($d) {
    $result: 0;
    $number: inspect($d);
    $power: 0;
    @for $index from str-length($number) through 1 {
        $digit: str-slice($number, $index, $index);
        $value: index($hex-chars, $digit) - 1;
        $result: $result + ($value * pow(16, $power) );
        $power: $power + 1;
    }
    @return $result;
}

十进制数被认为是数字,而十六进制被认为是字符串

于 2020-05-06T12:44:41.310 回答
-1

我会这样做:

$icons: "000", "001", "002";

@function icon($i) {
  @return "\F#{nth($icons, 1)}";
}

h1::before {
  content: icon(1);
}

编辑:

如果要将单词与值相关联,请尝试使用列表列表并遍历它们。我不会假装这是非常有效的,但它确实有效。如果 Sass 有哈希就好了。

$icons: '000' calendar, '001' inbox, '002' home

@function icon($call)
  @for $i from 1 through length($icons)
    @if $call == nth(nth($icons, $i), 2)
      @return "\F#{nth(nth($icons, $i), 1)}"

h1::before
  content: icon(calendar)
于 2013-04-12T01:07:33.297 回答