Skip to content

Commit ceb3a3e

Browse files
committed
Speed up 'difference', add findIndexSTArray
1 parent 8f9dc9c commit ceb3a3e

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

src/Data/Array.purs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import Control.Alt ((<|>))
114114
import Control.Alternative (class Alternative)
115115
import Control.Lazy (class Lazy, defer)
116116
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM2)
117+
import Control.Monad.Eff (runPure, foreachE)
117118

118119
import Data.Foldable (class Foldable, foldl, foldr)
119120
import Data.Foldable (foldl, foldr, foldMap, fold, intercalate, elem, notElem, find, findMap, any, all) as Exports
@@ -123,6 +124,7 @@ import Data.Traversable (scanl, scanr) as Exports
123124
import Data.Traversable (sequence)
124125
import Data.Tuple (Tuple(..))
125126
import Data.Unfoldable (class Unfoldable, unfoldr)
127+
import Data.Array.ST (runSTArray, pokeSTArray, findIndexSTArray, thaw)
126128

127129
import Partial.Unsafe (unsafePartial)
128130

@@ -583,9 +585,16 @@ deleteBy eq x ys = maybe ys (\i -> unsafePartial $ fromJust (deleteAt i ys)) (fi
583585
-- | Delete the first occurrence of each element in the second array from the
584586
-- | first array, creating a new array.
585587
difference :: forall a. Eq a => Array a -> Array a -> Array a
586-
difference xs ys
587-
| null xs = []
588-
| otherwise = uncons' (const xs) (\z zs -> delete z xs \\ zs) ys
588+
difference xs ys = catMaybes $ runPure $ runSTArray do
589+
zs <- thaw (map Just xs)
590+
foreachE ys \y -> do
591+
idx <- findIndexSTArray (_ == Just y) zs
592+
case idx of
593+
Just i ->
594+
void $ pokeSTArray zs i Nothing
595+
_ ->
596+
pure unit
597+
pure zs
589598

590599
infix 5 difference as \\
591600

src/Data/Array/ST.js

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

61+
exports.findIndexSTArrayImpl = function (just) {
62+
return function (nothing) {
63+
return function (f) {
64+
return function (xs) {
65+
return function () {
66+
for (var i = 0, l = xs.length; i < l; i++) {
67+
if (f(xs[i])) return just(i);
68+
}
69+
return nothing;
70+
};
71+
};
72+
};
73+
};
74+
};
75+
6176
exports.toAssocArray = function (xs) {
6277
return function () {
6378
var n = xs.length;

src/Data/Array/ST.purs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Data.Array.ST
1212
, pushSTArray
1313
, pushAllSTArray
1414
, spliceSTArray
15+
, findIndexSTArray
1516
, freeze, thaw
1617
, toAssocArray
1718
) where
@@ -96,6 +97,22 @@ foreign import spliceSTArray
9697
-> Array a
9798
-> Eff (st :: ST h | r) (Array a)
9899

100+
-- | Find the first index for which a predicate holds.
101+
findIndexSTArray
102+
:: forall a h r
103+
. (a -> Boolean)
104+
-> STArray h a
105+
-> Eff (st :: ST h | r) (Maybe Int)
106+
findIndexSTArray = findIndexSTArrayImpl Just Nothing
107+
108+
foreign import findIndexSTArrayImpl
109+
:: forall a h r
110+
. (forall t. t -> Maybe t)
111+
-> (forall t. Maybe t)
112+
-> (a -> Boolean)
113+
-> STArray h a
114+
-> Eff (st :: ST h | r) (Maybe Int)
115+
99116
-- | Create an immutable copy of a mutable array, where each element
100117
-- | is labelled with its index in the original array.
101118
foreign import toAssocArray

0 commit comments

Comments
 (0)