List operations that can be applied in either Direction
Alter the element at the given index in a Direction
import Linear exposing (Direction(..))
[ 1, 2, 2 ]
|> List.Linear.elementAlter ( Down, 0 )
(\n -> n + 1)
--> [ 1, 2, 3 ]Do nothing if the index is out of range
import Linear exposing (Direction(..))
[ 0, 1, 2, 3 ]
|> List.Linear.elementAlter ( Up, 4 )
(\n -> n + 1)
--> [ 0, 1, 2, 3 ]
[ 0, 1, 2, 3 ]
|> List.Linear.elementAlter ( Up, -1 )
(\n -> n + 1)
--> [ 0, 1, 2, 3 ]If you're using at-operations often, consider using an Array instead of a List
to get O(log n) vs. O(n) random access performance
Pad in a Direction based on how much it takes to reach at a given length
import Linear exposing (Direction(..))
[ 1, 2 ]
|> List.Linear.padToAtLeast Up
4
(\l -> List.repeat l 0)
--> [ 1, 2, 0, 0 ]
[ 1, 2 ]
|> List.Linear.padToAtLeast Down
4
(\l -> List.repeat l 0)
--> [ 0, 0, 1, 2 ]To achieve "resize" behavior, use
padToAtLeast direction length followed by take direction length
[ 1, 2, 3 ]
|> List.Linear.padToAtLeast Up
2
(\l -> List.repeat l 0)
|> List.Linear.take Up 2
--> [ 1, 2 ]
[ 1, 2, 3 ]
|> List.Linear.padToAtLeast Down
2
(\l -> List.repeat l 0)
|> List.Linear.take Down 2
--> [ 2, 3 ]Reduce in a Direction
from a given initial accumulated thing
import Linear exposing (Direction(..))
[ 'l', 'i', 'v', 'e' ]
|> List.Linear.foldFrom "" Up String.cons
--> "evil"
[ 'l', 'i', 'v', 'e' ]
|> List.Linear.foldFrom "" Down String.cons
--> "live"A fold that can stop
→ (Complete the fold)
early instead of traversing the whole List
-- from lue-bird/elm-partial-or-complete
import PartialOrComplete exposing (PartialOrComplete(..))
import Linear exposing (Direction(..))
[ 2, -1, 4, 8 ]
-- take from the right while not negative
|> List.Linear.foldUntilCompleteFrom []
Down
(\n soFar ->
if n < 0 then
Complete soFar -- stop the fold
else
Partial (n :: soFar)
)
-- even if none are negative
|> PartialOrComplete.value
--> [ 4, 8 ]If negative elements exist, our foldUntilCompleteFrom will return
Complete with the list up to that point exclusive.
If the list only contains non-negative numbers, the result would be
Partial
with the whole list.
To treat both cases the same way, we use value, one of a few helpers from
PartialOrComplete
Compared to List.Extra.stoppableFoldl
you'll have the extra information about whether the fold completed or not,
as well as the ability to have different Complete and Partial types more in the spirit of
"parse, don't validate" (plus both Directions available).
Map each element using information collected from previous steps,
folding in a given Direction from given initial information.
Both the mapped Array and the folded information will be returned
You'll often find this under the name "mapAccum"
import Linear exposing (Direction(..))
[ 1, 2, 3 ]
|> List.Linear.mapFoldFrom 0
Down
(\state ->
{ element = state.folded
, folded = state.folded + state.element
}
)
--> { mapped = [ 5, 3, 0 ], folded = 6 }
mapIndexed : Direction -> (Int -> a -> b) -> (List a -> List b)
mapIndexed indexDirection mapAtIndex =
List.Linear.mapFoldFrom 0
indexDirection
(\state ->
{ element = state.element |> mapAtIndex state.folded
, folded = state.folded + 1
}
)
>> .mapped
[ 'h', 'i', 'y', 'o' ]
|> mapIndexed Up Tuple.pair
--> [ ( 0, 'h' ), ( 1, 'i' ), ( 2, 'y' ), ( 3, 'o' ) ]
[ 'h', 'i', 'y', 'o' ]
|> mapIndexed Down Tuple.pair
--> [ ( 3, 'h' ), ( 2, 'i' ), ( 1, 'y' ), ( 0, 'o' ) ]A given number of elements from one side in a Direction
import Linear exposing (Direction(..))
[ 1, 2, 3, 4 ]
|> List.Linear.take Up 2
--> [ 1, 2 ]
[ 1, 2, 3, 4 ]
|> List.Linear.take Down 2
--> [ 3, 4 ][] if the amount of elements to take is negative
import Linear exposing (Direction(..))
[ 1, 2, 3 ]
|> List.Linear.take Up -100
--> []Remove a given number of elements from one side in a Direction
import Linear exposing (Direction(..))
removeFirst =
List.Linear.drop Up 0
removeLast =
List.Linear.drop Down 0Nothing is dropped if the amount of elements to drop is negative
import Linear exposing (Direction(..))
[ 1, 2, 3 ]
|> List.Linear.drop Up -1
--> [ 1, 2, 3 ]Split into equal-sized chunks of a given length in a given Direction
The left over elements to one side are in remainder
import Linear exposing (Direction(..))
[ 1, 2, 3, 4, 5, 6, 7 ]
|> List.Linear.toChunksOf Up 3
--> { chunks = [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
--> , remainder = [ 7 ]
--> }
[ 1, 2, 3, 4, 5, 6, 7 ]
|> List.Linear.toChunksOf Down 3
--> { remainder = [ 1 ]
--> , chunks = [ [ 2, 3, 4 ], [ 5, 6, 7 ] ]
--> }
Justthe element at the given index in aDirectionNothingif the index is out of range:If you're using at-operations often, consider using an
Arrayinstead of aListto getO(log n)vs.O(n)random access performance