Skip to content

Commit f096cff

Browse files
committed
STArray: in-place sort
1 parent 32a1a20 commit f096cff

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

src/Data/Array/ST.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ exports.copyImpl = function (xs) {
5858
};
5959
};
6060

61+
exports.sortByImpl = function (comp) {
62+
return function (xs) {
63+
return function () {
64+
return xs.sort(function (x, y) {
65+
return comp(x)(y);
66+
});
67+
};
68+
};
69+
};
70+
6171
exports.toAssocArray = function (xs) {
6272
return function () {
6373
var n = xs.length;

src/Data/Array/ST.purs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ module Data.Array.ST
1414
, modifySTArray
1515
, pushAllSTArray
1616
, spliceSTArray
17+
, sort
18+
, sortBy
1719
, freeze
1820
, thaw
1921
, unsafeFreeze
@@ -80,6 +82,29 @@ foreign import emptySTArray :: forall a h r. Eff (st :: ST h | r) (STArray h a)
8082
thaw :: forall a h r. Array a -> Eff (st :: ST h | r) (STArray h a)
8183
thaw = copyImpl
8284

85+
-- | Sort a mutable array in place.
86+
sort :: forall a h r. Ord a => STArray h a -> Eff (st :: ST h | r) (STArray h a)
87+
sort = sortBy compare
88+
89+
-- | Sort a mutable array in place using a comparison function.
90+
sortBy
91+
:: forall a h r
92+
. (a -> a -> Ordering)
93+
-> STArray h a
94+
-> Eff (st :: ST h | r) (STArray h a)
95+
sortBy comp = sortByImpl comp'
96+
where
97+
comp' x y = case comp x y of
98+
GT -> 1
99+
EQ -> 0
100+
LT -> -1
101+
102+
foreign import sortByImpl
103+
:: forall a h r
104+
. (a -> a -> Int)
105+
-> STArray h a
106+
-> Eff (st :: ST h | r) (STArray h a)
107+
83108
-- | Create an immutable copy of a mutable array.
84109
freeze :: forall a h r. STArray h a -> Eff (st :: ST h | r) (Array a)
85110
freeze = copyImpl

test/Test/Data/Array/ST.purs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Prelude
44
import Control.Monad.Eff (Eff)
55
import Control.Monad.Eff.Console (log, CONSOLE)
66
import Control.Monad.ST (ST, pureST)
7-
import Data.Array.ST (STArray, emptySTArray, freeze, peekSTArray, pokeSTArray, pushAllSTArray, pushSTArray, spliceSTArray, thaw, toAssocArray, unsafeThaw, unsafeFreeze)
7+
import Data.Array.ST (STArray, emptySTArray, freeze, peekSTArray, pokeSTArray, pushAllSTArray, pushSTArray, sort, sortBy, spliceSTArray, thaw, toAssocArray, unsafeThaw, unsafeFreeze)
88
import Data.Foldable (all)
99
import Data.Maybe (Maybe(..), isNothing)
1010
import Test.Assert (assert, ASSERT)
@@ -132,6 +132,16 @@ testArrayST = do
132132
void $ pokeSTArray arr 1 2
133133
pure arr) == [1]
134134

135+
log "sort should reorder a list into ascending order based on the result of compare"
136+
assert $ run (
137+
sort =<< unsafeThaw [1, 3, 2, 5, 6, 4]
138+
) == [1, 2, 3, 4, 5, 6]
139+
140+
log "sortBy should reorder a list into ascending order based on the result of a comparison function"
141+
assert $ run (
142+
sortBy (flip compare) =<< unsafeThaw [1, 3, 2, 5, 6, 4]
143+
) == [6, 5, 4, 3, 2, 1]
144+
135145
log "spliceSTArray should be able to delete multiple items at a specified index"
136146

137147
assert $ run (do

0 commit comments

Comments
 (0)