Data.Array.Extra
- Package
- purescript-arrays-extra
- Repository
- flip111/purescript-arrays-extra
Some specialized functions can be found here.
#sortByMultiple Source
sortByMultiple :: forall a. Array (a -> a -> Ordering) -> Array a -> Array a
Sort by multiple comparison functions. Similar to SQL where you can specificy multiple columns with ASC and DESC. When a comparison function gives EQ the next one is tried.
Other functions don't have a Multiple variant such as sortOnByMultiple. Because the implementation of this function is so simple it serves as example function.
sortByMultiple comps xs = sortBy (fold comps) xs
let datas = [{a: 2, b: 4}, {a: 3, b: 4}, {a: 2, b: 5}, {a: 1, b: 5}]
a {a: a1} {a: a2} = compare a1 a2
b {b: b1} {b: b2} = compare b1 b2 -- use flip for DESC, or alternatively: compare b2 b1
in sortByMultiple [a, flip b] datas = [{a: 1, b: 5}, {a: 2, b: 5}, {a: 2, b: 4}, {a: 3, b: 4}]
#sortOn' Source
sortOn' :: forall a b. Ord b => (a -> b) -> Array a -> Array a
Sort a list by a projection.
This version of sortOn uses the decorate-sort-undecorate paradigm or Schwartzian transform. Which means the projection for each entry will only be computed once at the cost of creating more data structures. You will have to benchmark your specific situation to find out whether sortOn
or sortOn'
is faster.
sortOn' (\x -> if x == "dog" then 2 else 1) ["apple", "dog", "kiwi"] = ["apple", "kiwi", "dog"]
#sortOnBy' Source
sortOnBy' :: forall a b. (a -> b) -> (b -> b -> Ordering) -> Array a -> Array a
Sort a list by a projection and sort by a given comparison function.
This version of sortOnBy uses the decorate-sort-undecorate paradigm or Schwartzian transform. Which means the projection for each entry will only be computed once at the cost of creating more data structures. You will have to benchmark your specific situation to find out whether sortOnBy
or sortOnBy'
is faster.
sortOnBy' (\x -> if x == "dog" then 2 else 1) compare ["apple", "dog", "kiwi"] = ["apple", "kiwi", "dog"]
#sortOnByMaybe Source
sortOnByMaybe :: forall a b. (a -> Maybe b) -> (b -> b -> Ordering) -> Array a -> Array a
Sort a list by a projection and sort by a given comparison function. When the projection returns Nothing those items will be placed last. Useful if your Array contains items with missing data to sort on
sortOnByMaybe (\x -> if x == "dog" then Just 2 else Just 1) compare ["apple", "dog", "kiwi"] = ["apple", "kiwi", "dog"]
#sortOnByMaybe' Source
sortOnByMaybe' :: forall a b. (a -> Maybe b) -> (b -> b -> Ordering) -> Array a -> Array a
Sort a list by a projection and sort by a given comparison function.
When the projection returns Nothing those items will be placed last. Useful if your Array contains items with missing data to sort on
This version of sortOnByMaybe uses the decorate-sort-undecorate paradigm or Schwartzian transform. Which means the projection for each entry will only be computed once at the cost of creating more data structures. You will have to benchmark your specific situation to find out whether sortOnByMaybe
or sortOnByMaybe'
is faster.
sortOnByMaybe' (\x -> if x == "dog" then Just 2 else Just 1) compare ["apple", "dog", "kiwi"] = ["apple", "kiwi", "dog"]
#partitionEithers Source
partitionEithers :: forall a l r. (a -> Either l r) -> Array a -> { left :: Array l, right :: Array r }
Partitions an array of Either into two arrays. All the Left elements are put, in order, into the left field of the output record. Similarly the Right elements are put into the right field of the output record.
Note that this function is an alias for partitionMap
from Data.Filterable
.
The function is included in this library for people who prefer this name for the function as they might be used to it from haskell
partitionEithers (\a -> if a > 2 then Left a else Right a) [1,2,3,4] == {left: [1,2], right: [3,4]}
#combinations Source
combinations :: forall a. Int -> Array a -> Maybe (Array (NonEmptyArray a))
Get all combinations when drawing n elements from an array.
n must be greater than 0 and not greater than the length of the array otherwise this function returns Nothing
let products = [{product: "bread", amount: 1}, {product: "cheese", amount: 2}, {product: "bread", amount: 3}]
combinations 2 [1,2,3] -> Just [[1,2], [2,3], [1,3]]
#interleave Source
interleave :: forall a. Array (Array a) -> Array a
Takes an element from each array in turn to produce a new array.
interleave [[1,2], [3,4]] = [1,3,2,4]
concat [[1,2], [3,4]] = [1,2,3,4]
Re-exports from Data.Foldable.Extra
#sameElements Source
sameElements :: forall a f. Foldable f => Eq a => f a -> f a -> Boolean
Checks if two arrays have exactly the same elements. The order of elements does not matter.
sameElements ["A", "B", "B"] ["B", "A", "B"] == true
sameElements ["A", "B", "B"] ["A", "B"] == false
#partitionMaybe Source
partitionMaybe :: forall a b f. Foldable f => (a -> Maybe b) -> f a -> { no :: Array a, yes :: Array b }
Try to make a projection from an array. Return an array with the projection and the original array with the elements removed.
partitionMaybe (\x -> if x == "dog" then Just "cat" else Nothing) ["apple", "dog", "kiwi"] == { no: ["apple", "kiwi"], yes: ["cat"] }
#occurrencesMap Source
occurrencesMap :: forall a f. Foldable f => Ord a => f a -> Map a Int
Count the amount of times a value occurs in an array.
Requires an Ord instance for Map. This function should be faster than occurrences
occurrencesMap ["A", "B", "B"] == Map.fromList [Tuple "A" 1, Tuple "B" 2]
#mapMaybeAny Source
mapMaybeAny :: forall f a. Foldable f => (a -> Maybe a) -> f a -> Maybe (Array a)
Map an array conditionally, only return the array when at least one element was mapped. Elements that are not mapped will keep the old value.
mapMaybeAny (\_ -> Nothing) [1,2,3] == Nothing
mapMaybeAny (\x -> if x == 2 then Just 99 else Nothing) [1,2,3] == Just [1,99,3]
#mapEither Source
mapEither :: forall a b c f. Foldable f => (a -> Either c b) -> f a -> Either (Array c) (Array b)
Map with a function that yields Either
. Only succeeding when all elements where mapped to Right
.
Hint: if you don't care about collecting all the Left's (error conditions) and you are looking for a function like
forall a b c. (a -> Either c b) -> Array a -> Either c (Array b)
then use traverse
from Data.Traversable
.
#groupMaybeMap Source
groupMaybeMap :: forall a b c f. Foldable f => Eq b => (a -> Maybe b) -> (a -> c) -> f a -> Array (Tuple b (NonEmptyArray c))
Similar to groupMaybe
, adds the ability to map over the thing being grouped.
Useful for removing data that was only there to do the grouping.
groupMaybeMap (\x -> Just $ if even x then "even" else "odd") (*3) [1,2,3] == [(Tuple "odd" [3,9]), (Tuple "even" [6])]
groupMaybeMap f identity xs = groupMaybe f xs
#groupMaybe Source
groupMaybe :: forall f a b. Foldable f => Eq b => (a -> Maybe b) -> f a -> Array (Tuple b (NonEmptyArray a))
Similar to group
, adds the ability to group by a projection.
The projection is returned as the first argument of the Tuple.
groupMaybe (\x -> Just $ if even x then "even" else "odd") [1,2,3] == [(Tuple "odd" [1,3]), (Tuple "even" [2])]
#anyPredicate Source
anyPredicate :: forall f a. Foldable f => f (a -> Boolean) -> (a -> Boolean)
Combines multiple predicates into one. Only one has to match.
let preds = anyPredicate [(_ > 5), (_ > 10)]
all preds [5,10] == true
all preds [1,5,10] == false
any preds [1,5] == true
any preds [1] == false
#allPredicate Source
allPredicate :: forall f a. Foldable f => f (a -> Boolean) -> (a -> Boolean)
Combines multiple predicates into one. All have to match.
let preds = allPredicate [(_ > 5), (_ > 10)]
all preds [10,20] == true
all preds [5,10,20] == false
any preds [1,5,10] == true
any preds [1,5] == false
Re-exports from Data.Semigroup.Foldable.Extra
#mapAny Source
mapAny :: forall a f. Traversable1 f => (a -> Maybe a) -> f a -> Maybe (f a)
Map an array conditionally, only return the array when at least one element was mapped. Elements that are not mapped will keep the old value.
Hint: mapAll can be found in Data.Semigroup.Traversable.Extra
mapAny (\_ -> Nothing) (Data.Array.NonEmpty.cons' 1 [2, 3]) == Nothing
mapAny (\x -> if x == 2 then Just 99 else Nothing) (Data.Array.NonEmpty.cons' 1 [2, 3]) == Data.Array.NonEmpty.fromArray [1,99,3]
Not that in the second example the Just
is implicit.
Re-exports from Data.Traversable.Extra
#mapModify Source
mapModify :: forall a f. Traversable f => (a -> { new :: a, old :: a }) -> f a -> Tuple (Array a) (f a)
Like map but extracts the replaced values into an array. Allows modification of the replaced values as well.
#mapMaybeWriteModify Source
mapMaybeWriteModify :: forall a f. Traversable f => (a -> Maybe { new :: a, old :: a }) -> f a -> Tuple (Array a) (f a)
Same as mapMaybeWrite but allows modification of replaced values before returning them. Useful when the old and new values need to be linked to each other.
#mapMaybeWrite Source
mapMaybeWrite :: forall a f. Traversable f => (a -> Maybe a) -> f a -> Tuple (Array a) (f a)
Conditionally map the function over the the functor. Returns a Tuple with the new functor and the replaced values.
#mapAll Source
mapAll :: forall a b f. Traversable f => (a -> Maybe b) -> f a -> Maybe (f b)
Map an array conditionally, only return the array when all elements were mapped.
Note that this function is an alias for traverse
. This is specific behavior for the implementation of <*>
for Applicative Maybe
.
Hint: mapAny can be found in Data.Foldable.Extra
mapAll (\x -> if x == 2 then Just 99 else Nothing) [1,2,3] == Nothing
mapAll (\x -> Just (x * 2)) [1,2,3] == Just [2,4,6]