-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(list): introduce aperture, find, includes, prepend, split-every
- Loading branch information
Showing
10 changed files
with
321 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
@use 'sass:math'; | ||
@import 'slice'; | ||
@import 'inc'; | ||
|
||
/// Returns a new list, composed of n-tuples of consecutive elements. If `n` is | ||
/// greater than the length of the list, an empty list is returned. | ||
/// | ||
/// @group list | ||
/// @param {Number} n The size of the tuples to create | ||
/// @param {Array} list The list to split into `n`-length tuples | ||
/// @return {Array} The resulting list of `n`-length tuples | ||
/// | ||
/// @example scss - aperture | ||
/// | ||
/// $consecutive: aperture(2, (1, 2, 3, 4, 5); | ||
/// @debug $consecutive; //=> (1 2) (2 3) (3 4) (4 5) | ||
|
||
@function aperture($n, $list) { | ||
@if ($n > length($list)) { | ||
@return (); | ||
} | ||
$result: (); | ||
$idx: 1; | ||
$step: $n - 1; | ||
$list-length: length($list); | ||
$slice-to: if($n > $list-length, $list-length, $n); | ||
@while $idx <= $list-length { | ||
@if $idx > $list-length - $step { | ||
@return $result; | ||
} | ||
$slice: slice($idx, $slice-to, $list); | ||
$result: append($result, $slice); | ||
$idx: $idx + 1; | ||
$slice-to: math.clamp($idx, $idx + $step, $list-length); | ||
} | ||
@return $result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
@import 'inc'; | ||
@import './internal/run-function-with-params'; | ||
|
||
/// Returns the first element of the list which matches the predicate, or | ||
/// `null` if no element matches. | ||
/// | ||
/// @group list | ||
/// @param {Function} pred The predicate function used to determine if the element is the desired one. | ||
/// @param {Array} list The array to consider. | ||
/// @return {*} The element found, or `null`. | ||
/// @see reject | ||
/// | ||
/// @example scss - find | ||
/// | ||
/// @function isEven($n) { | ||
/// @return $n % 2 == 0; | ||
/// } | ||
/// $find-first-even: find(isEven, (1, 2, 3, 4)); | ||
/// @debug $find-first-even; //=> (2 4) | ||
|
||
@function find($pred, $list) { | ||
$idx: 1; | ||
@while $idx <= length($list) { | ||
$result: call(get-function($pred), nth($list, $idx)); | ||
@if $result { | ||
@return nth($list, $idx); | ||
} | ||
$idx: inc($idx); | ||
} | ||
@return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
@import 'equals'; | ||
@import 'inc'; | ||
|
||
/// Returns `true` if the specified value is equal, in [`equals`](#equals) | ||
/// terms, to at least one element of the given list; `false` otherwise. | ||
/// Also works with strings. | ||
/// | ||
/// @group list | ||
/// @param {*} a The item to compare against. | ||
/// @param {Array|String} list The array to consider. | ||
/// @return {Boolean} `true` if an equivalent item is in the list, `false` otherwise. | ||
/// @see dec | ||
/// | ||
/// @example scss - includes | ||
/// | ||
/// $has-seventeen: includes(17, (1, 5, 6, 11, 17, 28)); | ||
/// @debug $has-seventeen; //=> true | ||
|
||
@function includes($a, $list) { | ||
$idx: 1; | ||
|
||
@if (type-of($list) == 'string') { | ||
// not the prettiest but probably best to return truthy. | ||
@return if(str-index($list, $a), true, false); | ||
} | ||
|
||
@while $idx <= length($list) { | ||
@if (equals(nth($list, $idx), $a)) { | ||
@return true; | ||
} | ||
$idx: inc($idx); | ||
} | ||
@return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
@import 'concat'; | ||
|
||
/// | ||
/// Returns a new list with the given element at the front, followed by the | ||
/// contents of the list. | ||
/// | ||
/// @group list | ||
/// @param {*} el The item to add to the head of the output list. | ||
/// @param {Array} list The array to add to the tail of the output list. | ||
/// @return {Array} A new array. | ||
/// | ||
/// @example scss - prepend | ||
/// | ||
/// R.prepend('fee', ('fi', 'fo', 'fum')); //=> ('fee', 'fi', 'fo', 'fum') | ||
//// | ||
|
||
@function prepend($el, $list) { | ||
@return concat(append((), $el), $list); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
@use 'sass:math'; | ||
@import 'slice'; | ||
@import 'inc'; | ||
|
||
/// Splits a collection into slices of the specified length. | ||
/// | ||
/// @group list | ||
/// @param {Number} n | ||
/// @param {Array} list | ||
/// @return {Array} | ||
/// @see implode | ||
/// | ||
/// @example scss - split-every | ||
/// | ||
/// $splitted: split-every(2, (1, 2, 3, 4)); | ||
/// @debug $splitted; //=> (1 2) (3 4); | ||
|
||
@function split-every($n, $list) { | ||
@if $n <= 0 { | ||
@error "First argument to split-every must be a positive integer"; | ||
} | ||
$result: (); | ||
$idx: 1; | ||
$list-length: if( | ||
type-of($list) == 'string', | ||
str-length($list), | ||
length($list) | ||
); | ||
$slice-to: if($n > $list-length, $list-length, $n); | ||
|
||
@while $idx <= $list-length { | ||
$slice: slice($idx, $slice-to, $list); | ||
$result: append($result, $slice); | ||
$idx: $slice-to + 1; | ||
$slice-to: math.clamp($idx, $slice-to + $n, $list-length); | ||
} | ||
|
||
@return $result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
@import 'true'; | ||
@import '../src/aperture'; | ||
|
||
@include describe('aperture [function]') { | ||
@include it('creates a list of n-tuples from a list') { | ||
$seven-ls: (1, 2, 3, 4, 5, 6, 7); | ||
@include assert-equal( | ||
aperture(1, $seven-ls), | ||
(1) (2) (3) (4) (5) (6) (7), | ||
$inspect: true | ||
); | ||
@include assert-equal( | ||
aperture(2, $seven-ls), | ||
(1 2) (2 3) (3 4) (4 5) (5 6) (6 7), | ||
$inspect: true | ||
); | ||
@include assert-equal( | ||
aperture(3, $seven-ls), | ||
(1 2 3) (2 3 4) (3 4 5) (4 5 6) (5 6 7), | ||
$inspect: true | ||
); | ||
@include assert-equal( | ||
aperture(4, (1, 2, 3, 4)), | ||
append((), (1 2 3 4)), | ||
$inspect: true | ||
); | ||
} | ||
|
||
@include it('returns an empty list when `n` > `list.length`') { | ||
@include assert-equal(aperture(6, (1, 2, 3)), ()); | ||
@include assert-equal(aperture(1, ()), ()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
@import 'true'; | ||
@import '../src/find'; | ||
|
||
@function _find_spec_isEven($n) { | ||
@if type-of($n) == 'number' { | ||
@return $n % 2 == 0; | ||
} | ||
@return false; | ||
} | ||
@function _find_spec_gt-100($n) { | ||
@if type-of($n) == 'number' { | ||
@return $n > 100; | ||
} | ||
@return false; | ||
} | ||
@function _find_spec_is-string($str) { | ||
@return type-of($str) == 'string'; | ||
} | ||
@function _find_spec_x-gt-100($o) { | ||
@if type-of($o) == 'map' { | ||
@return map-get($o, 'x') > 100; | ||
} | ||
@return false; | ||
} | ||
|
||
@include describe('find [function]') { | ||
$obj: ( | ||
x: 200, | ||
); | ||
$a: [11, 10, 9, 'cow', $obj, 8, 7, 100, 200, 300, 4, 3, 2, 1, 0]; | ||
|
||
@include it('returns the first element that satisfies the predicate') { | ||
@include assert-equal(find(_find_spec_isEven, $a), 10); | ||
@include assert-equal(find(_find_spec_gt-100, $a), 200); | ||
@include assert-equal(find(_find_spec_is-string, $a), 'cow'); | ||
@include assert-equal(find(_find_spec_x-gt-100, $a), $obj); | ||
} | ||
@include it('returns `null` when no element satisfies the predicate') { | ||
@include assert-equal(find(_find_spec_isEven, ('zing')), null); | ||
} | ||
@include it('returns `null` when given an empty list') { | ||
@include assert-equal(find(_find_spec_isEven, ()), null); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
@import 'true'; | ||
@import '../src/includes'; | ||
|
||
@include describe('includes [function]') { | ||
@include it('returns true if an element is in a list') { | ||
@include assert-true(includes(7, (1, 2, 3, 9, 8, 7, 100, 200, 300))); | ||
@include assert-true( | ||
includes( | ||
( | ||
name: 'Thor', | ||
), | ||
((name: 'Thor'), (name: 'Iron Man'), (name: 'Black Widow')) | ||
) | ||
); | ||
} | ||
|
||
@include it('returns false if an element is not in a list') { | ||
@include assert-false(includes(99, (1, 2, 3, 9, 8, 7, 100, 200, 300))); | ||
} | ||
|
||
@include it('returns false for the empty list') { | ||
@include assert-false(includes(1, ())); | ||
} | ||
|
||
@include it('returns true if substring is part of string') { | ||
@include assert-true(includes('ba', 'banana')); | ||
@include assert-false(includes('no thanks', 'yes please')); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
@import 'true'; | ||
@import '../src/prepend'; | ||
|
||
@include describe('prepend [function]') { | ||
@include it('adds the element to the beginning of the list') { | ||
@include assert-equal(prepend('x', ('y', 'z')), ('x' 'y' 'z')); | ||
@include assert-equal( | ||
prepend(('a', 'z'), ('x', 'y')), | ||
('a', 'z') 'x' 'y' | ||
); | ||
} | ||
|
||
@include it('works on empty list') { | ||
@include assert-equal(prepend(1, ()), (1), $inspect: true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
@import 'true'; | ||
@import '../src/split-every'; | ||
|
||
@include describe('split-every [function]') { | ||
@include it('splits a collection into slices of the specified length') { | ||
@include assert-equal( | ||
split-every(1, (1, 2, 3, 4)), | ||
(1) (2) (3) (4), | ||
$inspect: true | ||
); | ||
@include assert-equal( | ||
split-every(2, (1, 2, 3, 4)), | ||
(1 2) (3 4), | ||
$inspect: true | ||
); | ||
@include assert-equal( | ||
split-every(3, (1, 2, 3, 4)), | ||
(1 2 3) (4), | ||
$inspect: true | ||
); | ||
@include assert-equal( | ||
split-every(4, (1, 2, 3, 4)), | ||
append((), (1 2 3 4)), | ||
$inspect: true | ||
); | ||
@include assert-equal( | ||
split-every(5, (1, 2, 3, 4)), | ||
append((), (1 2 3 4)), | ||
$inspect: true | ||
); | ||
@include assert-equal(split-every(3, ()), ()); | ||
@include assert-equal(split-every(1, 'abcd'), ('a' 'b' 'c' 'd')); | ||
@include assert-equal(split-every(2, 'abcd'), ('ab') ('cd')); | ||
@include assert-equal(split-every(3, 'abcd'), ('abc') ('d')); | ||
@include assert-equal(split-every(4, 'abcd'), append((), ('abcd'))); | ||
@include assert-equal(split-every(5, 'abcd'), append((), ('abcd'))); | ||
@include assert-equal(split-every(3, ''), ()); | ||
} | ||
} |