Sass 没有提供任何内置方法来对值列表进行排序。借助字符串操作函数,我们可以构建一个函数来按照给定顺序对项目列表进行排序。
如果要排序的值仅为数字,则操作起来相当容易,因为 Sass 可以原生比较数字。
排序数字
/// Quick sort
/// @author Sam Richards
/// @param {List} $list - list to sort
/// @return {List}
@function quick-sort($list) {
$less: ();
$equal: ();
$large: ();
@if length($list) > 1 {
$seed: nth($list, ceil(length($list) / 2));
@each $item in $list {
@if ($item == $seed) {
$equal: append($equal, $item);
} @else if ($item < $seed) {
$less: append($less, $item);
} @else if ($item > $SEED) {
$large: append($large, $item);
}
}
@return join(join(quick-sort($less, $order), $equal), quick-sort($large, $order));
}
@return $list;
}
排序数字和字符串
但是,如果你打算对字符串和数字进行排序,这会涉及到相当多的复杂性,所以让我们一步一步来做。
首先,我们需要一个排序顺序。
/// Default order used to determine which string comes first
/// @type List
$default-order:
"!" "#" "$" "%" "&" "'" "(" ")" "*" "+" "," "-" "." "/" "[" "\" "]" "^" "_" "{" "|" "}" "~"
"0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
"a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" !default;
然后,我们需要一个辅助函数来确定哪个值先出现。
/// Compares two string to determine which comes first
/// @access private
/// @param {String} $a - first string
/// @parem {String} $b - second string
/// @param {List} $order - order to deal with
/// @return {Bool}
@function _str-compare($a, $b, $order) {
@if type-of($a) == "number" and type-of($b) == "number" {
@return $a < $b;
}
$a: to-lower-case($a + unquote(""));
$b: to-lower-case($b + unquote(""));
@for $i from 1 through min(str-length($a), str-length($b)) {
$char-a: str-slice($a, $i, $i);
$char-b: str-slice($b, $i, $i);
@if $char-a and $char-b and index($order, $char-a) != index($order, $char-b) {
@return index($order, $char-a) < index($order, $char-b);
}
}
@return str-length($a) < str-length($b);
}
最后但并非最不重要的是,我们可以构建我们的排序函数。最有效的实现(可以移植到 Sass)是 快速排序算法。
/// Quick sort
/// @author Kitty Giraudel
/// @param {List} $list - list to sort
/// @param {List} $order [$default-order] - order to use for sorting
/// @return {List}
/// @require {function} _str-compare
/// @require $default-order
@function quick-sort($list, $order: $default-order) {
$less: ();
$equal: ();
$large: ();
@if length($list) > 1 {
$seed: nth($list, ceil(length($list) / 2));
@each $item in $list {
@if $item == $seed {
$equal: append($equal, $item, list-separator($list));
} @else if _str-compare($item, $seed, $order) {
$less: append($less, $item, list-separator($list));
} @else if not _str-compare($item, $seed, $order) {
$large: append($large, $item, list-separator($list));
}
}
@return join(join(quick-sort($less, $order), $equal), quick-sort($large, $order));
}
@return $list;
}
如果你对这种函数的制作感兴趣,可以查看 用 Sass 实现冒泡排序算法,该算法出自 The Sass Way。
快速排序函数中存在一个错误
第 17 行:
@else if $seed > $item {
应该改为@else if $item > $seed
。你无意中交换了两个参数和运算符 ;)这是一个 CSS/SASS 的有趣用法,但我不想在生产中使用它:排序应该在代码中使用 JS 完成,主要原因是 CSS 不会改变 DOM 顺序,这意味着你的键盘导航可访问性会很差