Skip to content

Commit

Permalink
Seq.sortBy
Browse files Browse the repository at this point in the history
  • Loading branch information
jmagaram committed Apr 24, 2023
1 parent bf0777f commit 545e66b
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 3 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
## Version 1.0.1
## Version 1.1.0

- Fix bug in `allPairs` where sequences are not cached.
- `Seq.reverse`
- `Seq.sortBy`
- `Seq.delay`

## Version 1.0.0

Expand Down
1 change: 1 addition & 0 deletions SEQ_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ let pairwise: t<'a> => t<('a, 'a)>
let reverse: t<'a> => t<'a>
let scan: (t<'a>, 'b, ('b, 'a) => 'b) => t<'b>
let scani: (t<'a>, ~zero: 'b, (~sum: 'b, ~val: 'a, ~inx: int) => 'b) => t<'b>
let sortBy: (t<'a>, ('a, 'a) => int) => t<'a>
let takeAtMost: (t<'a>, int) => t<'a>
let takeUntil: (t<'a>, 'a => bool) => t<'a>
let takeWhile: (t<'a>, 'a => bool) => t<'a>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jmagaram/rescript-extras",
"version": "1.0.1",
"version": "1.1.0",
"module": "",
"description": "Useful general-purpose utility functions and modules for ReScript projects.",
"keywords": [
Expand Down
7 changes: 7 additions & 0 deletions src/Extras__Seq.res
Original file line number Diff line number Diff line change
Expand Up @@ -706,3 +706,10 @@ let reverse = xx =>
| _ => xx->fromArray(~start=xx->Js.Array2.length - 1, ~end=0)
}
})

let sortBy = (xx, compare) =>
delay(() => {
let xx = xx->toArray
xx->Js.Array2.sortInPlaceWith(compare)->ignore
xx->fromArray
})
8 changes: 8 additions & 0 deletions src/Extras__Seq.resi
Original file line number Diff line number Diff line change
Expand Up @@ -646,3 +646,11 @@ let reverse: t<'a> => t<'a>
sequence.
*/
let delay: (unit => t<'a>) => t<'a>

/**
`sortBy(source, compare)` consumes the entire `source` sequence as soon as that
sequence is iterated. As such it should not be used with large or infinite
sequences. The function uses a stable sort (the original order of equal elements
is preserved) based on the provided `compare` function.
*/
let sortBy: (t<'a>, ('a, 'a) => int) => t<'a>
45 changes: 44 additions & 1 deletion tests/Extras__SeqTests.res
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Option = Belt.Option
module Result = Belt.Result

let intToString = Belt.Int.toString
let intCompare = Ex.Cmp.int

let concatInts = xs =>
xs->Js.Array2.length == 0 ? "_" : xs->Js.Array2.map(intToString)->Js.Array2.joinWith("")
Expand Down Expand Up @@ -1578,13 +1579,54 @@ let orElseTests = makeSeqEqualsTests(
],
)

let sortByTests = makeSeqEqualsTests(
~title="sortBy",
[
(S.empty->S.sortBy(intCompare), [], ""),
(S.singleton(1)->S.sortBy(intCompare), [1], ""),
([1, 5, 2, 9, 7, 3]->S.fromArray->S.sortBy(intCompare), [1, 2, 3, 5, 7, 9], ""),
],
)->Js.Array2.concat([
T.make(~category="Seq", ~title="sortBy", ~expectation="completely lazy", ~predicate=() => {
S.repeatWith(3, () => {Js.Exn.raiseError("boom!")})
->S.sortBy(intCompare)
->S.takeAtMost(0)
->S.consume
->ignore
true
}),
T.make(~category="Seq", ~title="sortBy", ~expectation="stable", ~predicate=() => {
let sortByFirst = (a, b) => {
let (afst, _) = a
let (bfst, _) = b
intCompare(afst, bfst)
}
let data = [
(2, "x"),
(1, "x"),
(2, "y"),
(4, "x"),
(3, "x"),
(1, "y"),
(3, "y"),
(2, "z"),
(4, "y"),
(1, "z"),
(3, "z"),
(4, "z"),
]
let sorted = data->S.fromArray->S.sortBy(sortByFirst)->S.map(((_, letter)) => letter)->S.toArray
sorted == "xyzxyzxyzxyz"->Js.String2.split("")
}),
])

let delayTests = makeSeqEqualsTests(
~title="delay",
[
(S.delay(() => S.empty), [], ""),
(S.delay(() => S.singleton(1)), [1], ""),
(S.delay(() => oneToFive), [1, 2, 3, 4, 5], ""),
(S.delay(() => Js.Exn.raiseError("Boom!"))->S.takeAtMost(0), [], ""),
(S.delay(() => Js.Exn.raiseError("boom!"))->S.takeAtMost(0), [], ""),
],
)

Expand Down Expand Up @@ -1739,6 +1781,7 @@ let tests =
sampleZipLongest,
scanTests,
someTests,
sortByTests,
sortedMergeTests,
takeAtMostTests,
takeUntilTests,
Expand Down

0 comments on commit 545e66b

Please sign in to comment.