How do I get a sub array in Haskell?
I think you're looking for is the 'Derived arrays' section in the Data.Array documentation: http://hackage.haskell.org/packages/archive/array/latest/doc/html/Data-Array.html#5 which houses the function:
ixmap :: (Ix i, Ix j) => (i, i) -> (i -> j) -> Array j e -> Array i e
ixmap allows for transformations on array indices. It may be thought of as providing function composition on the right with the mapping that the original array embodies.
A similar transformation of array values may be achieved using fmap from the Array instance > of the Functor class.
The following code:
ixmap newBounds trans backingArray
would return an array with bounds newBounds
, and when indexed with !i
, the index transformation function is applied onto the index i
before being used to index backingArray
.
Example if you had the array "Hello World" (helloWorldArray below) and you want to only see "ell" as a derived zero-based (sub-)array:
> let helloWorldArray = listArray (0,length str - 1) str -- 0-based array
where str = "Hello World"
> let ellArray = ixmap (0,2) succ helloWorldArray -- also 0-based array
> ellArray ! 0
'e'
> ellArray ! 1
'l'
> ellArray ! 2
'l'
Here we say that our new array ellArray
has indices from 0
through 2
. Our index transformation is simply to add one (succ
), because we want to map the index range [0..2]
to [1..3]
in the original helloWorldArray
.
Of course, ixmap
is abstract enough to capture any index transformations: even as to view 2 dimensional arrays as 1 dimensional arrays and vice-versa. It's better to think of it as creating a 'view' onto array data rather than a 'sub-array' function.
For more examples you can look here: http://zvon.org/other/haskell/Outputarray/ixmap_f.html
Taking sub-arrays using the vector package is probably the easiest approach (assuming your question isn't actually asking about taking sub-lists).
The relevant functions from the general vector/array interface is:
:: Vector v a => Int -> Int -> v a -> v a
but you should also know about take and drop. slice takes a index and length, and extracts the sub-array.
I didn't find any direct way to get a sub-array (i.e. slice), but here's one way to do it via an intermediate list.
import Data.Array
subArray :: Int -> Int -> Array -> Array
subArray i j a = listArray (0,j-i) $ map (a!) [i..j]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With