lue-bird/elm-linear-direction/5.1.0

NOTE: the latest version is 11.2.0

Array.Linear

Array operations that can be applied in either direction.

scan

( DirectionLinear, Int )
-> Array element
-> Result ExpectedIndexInRange element

The element at an index in a direction.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ "lose", "win", "lose" ]
    |> Array.Linear.element ( Down, 0 )
--> "lose" |> Ok




Array.fromList [ "lose", "win", "lose" ]
    |> Array.Linear.element ( Up, 0 )
--> "lose" |> Ok

Err if the index is out of range.

import Linear exposing (DirectionLinear(..), ExpectedIndexInRange(..))
import Array


Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.element ( Up, -1 )
--> Err (ExpectedIndexForLength 3)


Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.element ( Up, 100 )
--> Err (ExpectedIndexForLength 3)

transform

( accumulationValue
, element -> accumulationValue -> accumulationValue
)
-> Array element
-> accumulationValue

Reduce an Array in a direction.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 'l', 'i', 'v', 'e' ]
    |> Array.Linear.foldFrom ( "", Up, String.cons )
--> "evil"


Array.fromList [ 'l', 'i', 'v', 'e' ]
    |> Array.Linear.foldFrom ( "", Down, String.cons )
--> "live"

alter

elementRemove : ( DirectionLinear, Int ) -> Array element -> Array element

Kick an element out of an Array at a given index in a direction.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 'a', 'a', 'b' ]
    |> Array.Linear.elementRemove ( Up, 1 )
--> Array.fromList [ 'a', 'b' ]


Array.fromList [ 'a', 'b', 'c', 'd' ]
    |> Array.Linear.elementRemove ( Down, 0 )
--> Array.fromList [ 'a', 'b', 'c' ]

If the index is out of bounds, nothing is changed.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 'a', 'a', 'b' ]
    |> Array.Linear.elementRemove ( Up, -1 )
--> Array.fromList [ 'a', 'a', 'b' ]


Array.fromList [ 'a', 'a', 'b' ]
    |> Array.Linear.elementRemove ( Up, 100 )
--> Array.fromList [ 'a', 'a', 'b' ]
( ( DirectionLinear, Int ), () -> element )
-> Array element
-> Array element

Set the element at an index in a direction.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ "I", "am", "ok" ]
    |> Array.Linear.elementReplace
        ( ( Up, 2 ), \() -> "confusion" )
--> Array.fromList [ "I", "am", "confusion" ]


Array.fromList [ "I", "am", "ok" ]
    |> Array.Linear.elementReplace
        ( ( Down, 1 ), \() -> "feel" )
--> Array.fromList [ "I", "feel", "ok" ]

If the index is out of range, the Array is unaltered.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ "I", "am", "ok" ]
    |> Array.Linear.elementReplace
        ( ( Up, -1 ), \() -> "is" )
--> Array.fromList [ "I", "am", "ok" ]
( ( DirectionLinear, Int ), () -> element )
-> Array element
-> Array element

Put an element in an Array at a given index in a direction.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 'a', 'c', 'd' ]
    |> Array.Linear.insert
        ( ( Up, 1 ), \() -> 'b' )
--> Array.fromList [ 'a', 'b', 'c', 'd' ]


Array.fromList [ 'a', 'c', 'd' ]
    |> Array.Linear.insert
        ( ( Down, 2 ), \() -> 'b' )
--> Array.fromList [ 'a', 'b', 'c', 'd' ]

If the index is out of bounds, nothing is inserted.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 'a', 'c', 'd' ]
    |> Array.Linear.insert
        ( ( Up, -1 ), \() -> 'b' )
--> Array.fromList [ 'a', 'c', 'd' ]


Array.fromList [ 'a', 'c', 'd' ]
    |> Array.Linear.insert
        ( ( Up, 4 ), \() -> 'b' )
--> Array.fromList [ 'a', 'c', 'd' ]

squeezeIn allows inserting a whole Array of elements.

{ lengthMinimum : Int
, pad : ( DirectionLinear, Int -> Array element )
}
-> Array element
-> Array element

Pad an Array in a direction.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 1, 2 ]
    |> Array.Linear.padTo
        { lengthMinimum = 4
        , pad = ( Up, \n -> Array.repeat n 0 )
        }
--> Array.fromList [ 1, 2, 0, 0 ]


Array.fromList [ 1, 2 ]
    |> Array.Linear.padTo
        { lengthMinimum = 4
        , pad = ( Down, \n -> Array.repeat n 0 )
        }
--> Array.fromList [ 0, 0, 1, 2 ]

padTo { .. length .. direction .. } |> take ( direction, length ) → "resize" behavior

Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.padTo
        { lengthMinimum = 2
        , pad = ( Up, \n -> Array.repeat n 0 )
        }
    |> Array.Linear.take ( Up, 2 )
--> Array.fromList [ 1, 2 ]


Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.padTo
        { lengthMinimum = 2
        , pad = ( Down, \n -> Array.repeat n 0 )
        }
    |> Array.Linear.take ( Down, 2 )
--> Array.fromList [ 2, 3 ]

part

take : ( DirectionLinear, Int ) -> Array element -> Array element

A given number of elements from one side.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 1, 2, 3, 4, 5, 6 ]
    |> Array.Linear.take ( Up, 4 )
    |> Array.Linear.take ( Down, 2 )
--> Array.fromList [ 3, 4 ]


Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.take ( Up, 100 )
--> Array.fromList [ 1, 2, 3 ]

Array.empty if the amount of elements to take is negative.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.take ( Up, -100 )
--> Array.empty
drop : ( DirectionLinear, Int ) -> Array element -> Array element

Remove a given number of elements from one side.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 1, 2, 3, 4, 5, 6 ]
    |> Array.Linear.drop ( Down, 2 )
--> Array.fromList [ 1, 2, 3, 4 ]


Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.drop ( Up, 100 )
--> Array.empty

Nothing is dropped if the amount of elements to drop is negative.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 1, 2, 3 ]
    |> Array.Linear.drop ( Up, -1 )
--> Array.fromList [ 1, 2, 3 ]
{ length : Int
, remainder : DirectionLinear
}
-> Array element
-> { chunks : Array (Array element)
, remainder : Array element
}

Split the Array into equal-length chunks. The left over elements to one side are in remainder.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 1, 2, 3, 4, 5, 6, 7 ]
    |> Array.Linear.toChunks
        { length = 3, remainder = Up }
--> { chunks =
-->     Array.fromList
-->         [ Array.fromList [ 1, 2, 3 ]
-->         , Array.fromList [ 4, 5, 6 ]
-->         ]
--> , remainder = Array.fromList [ 7 ]
--> }


Array.fromList [ 1, 2, 3, 4, 5, 6, 7 ]
    |> Array.Linear.toChunks
        { length = 3, remainder = Down }
--> { remainder = Array.fromList [ 1 ]
--> , chunks =
-->     Array.fromList
-->         [ Array.fromList [ 2, 3, 4 ]
-->         , Array.fromList [ 5, 6, 7 ]
-->         ]
--> }

glue

( ( DirectionLinear, Int ), () -> Array element )
-> Array element
-> Array element

Put elements of a given Array between the elements left and right to the given index in a direction.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 'a', 'd', 'e' ]
    |> Array.Linear.squeezeIn
        ( ( Up, 1 ), \() -> Array.fromList [ 'b', 'c' ] )
--> Array.fromList [ 'a', 'b', 'c', 'd', 'e' ]


Array.fromList [ 'a', 'd', 'e' ]
    |> Array.Linear.squeezeIn
        ( ( Down, 2 ), \() -> Array.fromList [ 'b', 'c' ] )
--> Array.fromList [ 'a', 'b', 'c', 'd', 'e' ]

If the index is outside of the Array's range, nothing is inserted.

import Linear exposing (DirectionLinear(..))
import Array


Array.fromList [ 'a', 'd', 'e' ]
    |> Array.Linear.squeezeIn
        ( ( Up, -1 ), \() -> Array.fromList [ 'b', 'c' ] )
--> Array.fromList [ 'a', 'd', 'e' ]


Array.fromList [ 'a', 'd', 'e' ]
    |> Array.Linear.squeezeIn
        ( ( Up, 4 ), \() -> Array.fromList [ 'b', 'c' ] )
--> Array.fromList [ 'a', 'd', 'e' ]

insert allows inserting a single element.