7

How do I get a sub array in Haskell?

5
  • 2
    Do you know how to get an array in the first place? What array library are you talking about? Data.Vector? Data.Array? This question really needs fleshed out. Commented Apr 2, 2011 at 8:27
  • @TomMD subArray of Data.Array Commented Apr 2, 2011 at 9:33
  • 1
    Data.Array is rather clumsy and has no fusion, I suggest you look to Data.Vector for future array needs. Commented Apr 2, 2011 at 16:07
  • newArray_ (0,x) :: IO (IOArray Int Sub) :-P Commented Apr 7, 2011 at 18:46
  • Don't forget to accept the answer that helped you in the end ;) Commented Sep 15, 2013 at 16:24

3 Answers 3

13

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

Sign up to request clarification or add additional context in comments.

Comments

4

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:

  • slice :: 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.

Comments

2

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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.