Skip to content

Commit 67969a3

Browse files
change JS implementation of count to use string iterator if possible
1 parent e3cea19 commit 67969a3

File tree

2 files changed

+24
-22
lines changed

2 files changed

+24
-22
lines changed

src/Data/String/CodePoints.js

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,23 @@ exports._codePointAt = function (fallback) {
4040
};
4141
};
4242

43-
exports._count = function (isLead) {
44-
return function (isTrail) {
45-
return function (unsurrogate) {
43+
exports._count = function (fallback) {
44+
return function (unsafeCodePointAt0) {
45+
if (hasStringIterator) {
4646
return function (pred) {
4747
return function (str) {
48-
var cpCount = 0;
49-
for (var cuCount = 0; cuCount < str.length; ++cuCount) {
50-
var lead = str.charCodeAt(cuCount);
51-
var cp = lead;
52-
if (isLead(lead) && cuCount + 1 < str.length) {
53-
var trail = str.charCodeAt(cuCount + 1);
54-
if (isTrail(trail)) {
55-
cp = unsurrogate(lead)(trail);
56-
++cuCount;
57-
}
58-
}
59-
if (!pred(cp)) return cpCount;
60-
++cpCount;
48+
var iter = str[Symbol.iterator]();
49+
for (var i = 0; i < str.length; ++i) {
50+
var o = iter.next();
51+
if (o.done) return i;
52+
var cp = unsafeCodePointAt0(o.value);
53+
if (!pred(cp)) return i;
6154
}
62-
return cpCount;
55+
return i;
6356
};
6457
};
65-
};
58+
}
59+
return fallback;
6660
};
6761
};
6862

src/Data/String/CodePoints.purs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ unsafeCodePointAt0Fallback s =
9090
-- | of code points from the beginning, if there is such a code point. Operates
9191
-- | in constant space and in time linear to `n`.
9292
codePointAt :: Int -> String -> Maybe CodePoint
93+
codePointAt n _ | n < 0 = Nothing
9394
codePointAt 0 "" = Nothing
9495
codePointAt 0 s = Just (unsafeCodePointAt0 s)
9596
codePointAt n s = _codePointAt codePointAtFallback Just Nothing unsafeCodePointAt0 n s
@@ -113,16 +114,23 @@ codePointAtFallback n s = case uncons s of
113114
-- | which all match the given predicate. Operates in constant space and in
114115
-- | time linear to the length of the given string.
115116
count :: (CodePoint -> Boolean) -> String -> Int
116-
count = _count isLead isTrail unsurrogate
117+
count = _count countFallback unsafeCodePointAt0
117118

118119
foreign import _count
119-
:: (Int -> Boolean)
120-
-> (Int -> Boolean)
121-
-> (Int -> Int -> CodePoint)
120+
:: ((CodePoint -> Boolean) -> String -> Int)
121+
-> (String -> CodePoint)
122122
-> (CodePoint -> Boolean)
123123
-> String
124124
-> Int
125125

126+
countFallback :: (CodePoint -> Boolean) -> String -> Int
127+
countFallback p s = countTail p s 0
128+
where
129+
countTail :: (CodePoint -> Boolean) -> String -> Int -> Int
130+
countTail p' s' accum = case uncons s' of
131+
Just { head, tail } -> if p' head then countTail p' tail (accum + 1) else accum
132+
_ -> accum
133+
126134

127135
-- | Drops the given number of code points from the beginning of the given
128136
-- | string. If the string does not have that many code points, returns the

0 commit comments

Comments
 (0)