Bryan O'Sullivan avatar Bryan O'Sullivan committed 9e2cdf4

Implement elemIndices

Comments (0)

Files changed (3)

     , findIndex
     , findIndices
     , elemIndex
-    -- , elemIndices
+    , elemIndices
     -- , count
 
     -- * Zipping and unzipping
 -- fusion.
 elemIndex :: Char -> Text -> Maybe Int
 elemIndex c t = S.elemIndex c (stream t)
+{-# INLINE elemIndex #-}
+
+-- | /O(n)/ The 'elemIndices' function returns the index of every
+-- element in the given 'Text' which is equal to the query
+-- element. This function is subject to fusion.
+elemIndices :: Char -> Text -> [Int]
+elemIndices c t = S.elemIndices c (stream t)
+{-# INLINE elemIndices #-}
 
 -------------------------------------------------------------------------------
 -- * Zipping

Data/Text/Fusion.hs

     , findIndices
     , findIndexOrEnd
     , elemIndex
+    , elemIndices
 
     -- * Zipping and unzipping
     , zipWith
 -- element in the given stream which is equal to the query
 -- element, or 'Nothing' if there is no such element.
 elemIndex :: Char -> Stream Char -> Maybe Int
-elemIndex a (Stream next s0 _len) = loop_elemIndex 0 s0
+elemIndex a s = case elemIndices a s of
+                  (i:_) -> Just i
+                  _     -> Nothing
+{-# INLINE [0] elemIndex #-}
+
+-- | /O(n)/ The 'elemIndices' function returns the index of every
+-- element in the given stream which is equal to the query element.
+elemIndices :: Char -> Stream Char -> [Int]
+elemIndices a (Stream next s0 _len) = loop 0 s0
   where
-    loop_elemIndex !i !s = case next s of
-      Done                   -> Nothing
-      Skip    s'             -> loop_elemIndex i     s'
-      Yield x s' | a == x    -> Just i
-                 | otherwise -> loop_elemIndex (i+1) s'
-{-# INLINE [0] elemIndex #-}
+    loop !i !s = case next s of
+      Done                   -> []
+      Skip    s'             -> loop i s'
+      Yield x s' | a == x    -> i : loop (i+1) s'
+                 | otherwise -> loop (i+1) s'
+{-# INLINE [0] elemIndices #-}
 
 -------------------------------------------------------------------------------
 -- * Zipping

tests/Properties.hs

 prop_findIndex p     = L.findIndex p `eqP` T.findIndex p
 prop_findIndices p   = L.findIndices p`eqP` T.findIndices p
 prop_elemIndex c     = L.elemIndex c `eqP` T.elemIndex c
+prop_elemIndices c   = L.elemIndices c`eqP` T.elemIndices c
 prop_zipWith c s     = L.zipWith c s `eqP` (unpack . T.zipWith c (pack s))
 
 main = run tests =<< getArgs
   ("prop_findIndex", mytest prop_findIndex),
   ("prop_findIndices", mytest prop_findIndices),
   ("prop_elemIndex", mytest prop_elemIndex),
+  ("prop_elemIndices", mytest prop_elemIndices),
   ("prop_zipWith", mytest prop_zipWith)
   ]
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.