1

Which function can I use to find its index of an element in an Array? For example, I want to find the index of 'x' in an Array (Data.Array)

lowerCase = listArray ((0,0),(1,12)) ['a'..]
2
  • What if there are many x in the array ? Basically, arrays are for accessing by index and if you need to find element's index then array is not the right data structure. Commented Feb 8, 2017 at 8:30
  • Thanks Ankur. In my case, I know there is no duplicate data in the array...I wanted to access data by a tuple and that's why I used Array. In that case, what data structure would you recommend? Commented Feb 8, 2017 at 14:22

2 Answers 2

2
fst <$> find ((== 'a') . snd) $ assocs lowerCase
Sign up to request clarification or add additional context in comments.

5 Comments

Why doesn't array have its own find or in this case elemIndex / elemIndices?
@Michael You can use find because Array has a Foldable instance. I don't know why there is not a elemIndex for Array.
Thank you! Just a small thing.. I added fromJust fst $ fromJust $ find ((== 'a') . snd) $ assocs lowerCase
Eii000 what about when the element doesn't exist?
Thanks Thomas! I check the output from "find ((== 'a') . snd) $ assocs lowerCase " and run the rest when it's not Nothing.
1

To get all the indices a certain element appears in your Data.Array the following list comprehension can be used:

results = [fst x | x <- (assocs lowerCase), snd x == 'a']

assocs has the following prototype:

assocs :: Ix i => Array i e -> [(i, e)]

It basically flattens a Data.Array in a List containing (i, e) pairs. For:

a = listArray ((0,0),(2,2)) ['a'..]

assocs a will output

[((0,0),'a'),((0,1),'b'),((0,2),'c'),((1,0),'d'),((1,1),'e'),((1,2),'f'),((2,0),'g'),((2,1),'h'),((2,2),'i')]

Now, in our list comprehension, we have x <- (assocs a), so x is generated by the list assocs a.

The list outputed by the list comprehension will contain only fst x where

snd x == theElementWeAreLookingFor

Every x generated by assocs a is checked and if the condition snd x == 'a' is met then fst a (the index) will be inserted in the output list.

Once the list is generated, it can be checked whether there are none, one or more outputs.

getElementIndex :: Array (Int, Int) Char -> Char -> Maybe (Int, Int)
getElementIndex a e
   | null results = Nothing
   | othwerwise   = Just $ head results
   where results = [fst x | x <- (assocs a), snd x == e]

A imperative pseduocode could look like:

results = []

for_each x in a.toList():
   if x.second == 'a':
      results.append(x.first)

2 Comments

Please add some explanation.
Done. Hope this helps

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.