|
| 1 | +// |
| 2 | +// Copyright 2025 Google LLC |
| 3 | +// SPDX-License-Identifier: Apache-2.0 |
| 4 | +// |
| 5 | + |
| 6 | +// Extensions to the go/sass:list built-in module. |
| 7 | + |
| 8 | +// go/keep-sorted start by_regex='(.+) prefix_order=sass: |
| 9 | +@use 'sass:list'; |
| 10 | +@use 'assert'; |
| 11 | +@use 'throw'; |
| 12 | +// go/keep-sorted end |
| 13 | + |
| 14 | +/// Returns the difference between two lists. |
| 15 | +/// |
| 16 | +/// @example scss |
| 17 | +/// $listA: ('apple', 'banana', 'cherry', 'date'); |
| 18 | +/// $listB: ('banana', 'cherry', 'apple'); |
| 19 | +/// $listC: ('apple', 'banana', 'date'); |
| 20 | +/// |
| 21 | +/// @debug list_ext.difference($listA, $listB); // ('date') |
| 22 | +/// @debug list_ext.difference($listA, $listC); // ('cherry') |
| 23 | +/// |
| 24 | +/// @param {list} $listA - The first list to compare. |
| 25 | +/// @param {list} $listB - The second list to compare. |
| 26 | +/// @return {list} All items in $listA that are not in $listB. |
| 27 | +@function difference($listA, $listB) { |
| 28 | + $listA: assert.is-type($listA, 'list', $source: 'list_ext.difference'); |
| 29 | + $listB: assert.is-type($listB, 'list', $source: 'list_ext.difference'); |
| 30 | + $error: throw.get-error($listA, $listB); |
| 31 | + @if $error { |
| 32 | + @return $error; |
| 33 | + } |
| 34 | + |
| 35 | + $result: (); |
| 36 | + @each $item in $listA { |
| 37 | + @if not list.index($listB, $item) { |
| 38 | + $result: list.append($result, $item, list.separator($listA)); |
| 39 | + } |
| 40 | + } |
| 41 | + @return $result; |
| 42 | +} |
| 43 | + |
| 44 | +/// Checks if two lists contain the same elements, regardless of their order. |
| 45 | +/// |
| 46 | +/// The function iterates through each list and verifies that every element in |
| 47 | +/// one list is present in the other. The order of elements does not affect the |
| 48 | +/// result. |
| 49 | +/// |
| 50 | +/// @example scss |
| 51 | +/// $listA: ('apple', 'banana', 'cherry'); |
| 52 | +/// $listB: ('banana', 'cherry', 'apple'); |
| 53 | +/// $listC: ('apple', 'banana', 'date'); |
| 54 | +/// |
| 55 | +/// @debug list_ext.are-equal($listA, $listB); // true |
| 56 | +/// @debug list_ext.are-equal($listA, $listC); // false |
| 57 | +/// |
| 58 | +/// @param {list} $listA - The first list to compare. |
| 59 | +/// @param {list} $listB - The second list to compare. |
| 60 | +/// @return {boolean} `true` if the lists contain the same elements, otherwise |
| 61 | +/// `false`. |
| 62 | +@function are-equal($listA, $listB) { |
| 63 | + $listA: assert.is-type($listA, 'list', $source: 'list_ext.are-equal'); |
| 64 | + $listB: assert.is-type($listB, 'list', $source: 'list_ext.are-equal'); |
| 65 | + $error: throw.get-error($listA, $listB); |
| 66 | + @if $error { |
| 67 | + @return $error; |
| 68 | + } |
| 69 | + @if list.length($listA) != list.length($listB) { |
| 70 | + @return false; |
| 71 | + } |
| 72 | + $result: true; |
| 73 | + @each $key in $listA { |
| 74 | + @if not list.index($listB, $key) { |
| 75 | + $result: false; |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + @each $key in $listB { |
| 80 | + @if not list.index($listA, $key) { |
| 81 | + $result: false; |
| 82 | + } |
| 83 | + } |
| 84 | + @return $result; |
| 85 | +} |
| 86 | + |
| 87 | +/// Returns the intersection of two lists. |
| 88 | +/// |
| 89 | +/// @example scss |
| 90 | +/// $listA: ('apple', 'banana', 'cherry', 'date'); |
| 91 | +/// $listB: ('banana', 'cherry', 'apple'); |
| 92 | +/// $listC: ('apple', 'banana', 'date'); |
| 93 | +/// |
| 94 | +/// @debug list_ext.intersection($listA, $listB); // ('apple', 'banana', 'cherry') |
| 95 | +/// @debug list_ext.intersection($listA, $listC); // ('apple', 'banana') |
| 96 | +/// |
| 97 | +/// @param {list} $listA - The first list to compare. |
| 98 | +/// @param {list} $listB - The second list to compare. |
| 99 | +/// @return {list} All items in $listA that are also in $listB. |
| 100 | +@function intersection($listA, $listB) { |
| 101 | + $listA: assert.is-type($listA, 'list', $source: 'list_ext.intersection'); |
| 102 | + $listB: assert.is-type($listB, 'list', $source: 'list_ext.intersection'); |
| 103 | + $error: throw.get-error($listA, $listB); |
| 104 | + @if $error { |
| 105 | + @return $error; |
| 106 | + } |
| 107 | + $result: (); |
| 108 | + @each $item in $listA { |
| 109 | + @if list.index($listB, $item) { |
| 110 | + $result: list.append($result, $item, list.separator($listA)); |
| 111 | + } |
| 112 | + } |
| 113 | + @return $result; |
| 114 | +} |
0 commit comments