core-extra icon indicating copy to clipboard operation
core-extra copied to clipboard

Add Array.Extra.getMany

Open gampleman opened this issue 1 year ago • 2 comments

getMany : Array Int -> Array a -> Maybe (Array a)

Like Array.get, but retrieves a number of elements all at once.

Array.fromList ["Alice", "Ben", "Charlie", "David"]
    |> getMany (Array.fromList [1, 3])
    --> Just (Array.fromList [ "Ben", "David" ])

Motivating use case

A list (or array) of indices is a fairly natural way to abstractly store a particular ordering of an array. Once you're done processing, you want to have a way to materialise the ordering.

Rationale

The way one would implement this is relatively straightforward, but mostly marred by excessive Maybe handling:

getMany indices array =
   Array.foldr (\index ->
      Maybe.map2 (::) (Array.get idea array)
   ) (Just []) indices
        |> Maybe.map Array.fromList

or some such. Not terrible, but easy to get the ordering wrong (which maybe I have, I didn't check).

Design alternatives

  1. It makes sense for this to be on Array and for the second argument to be an Array, but the first argument could easily be a list and so could the return type. It sort of seems more consistent for everything to be an Array :shrug:.
  2. We could easily make it so that it would not return a Maybe if an index wasn't found. Instead the missing index would simply be ignored. It would be relatively easy to detect that case, since then Array.length return /= Array.length indices.

gampleman avatar Jan 23 '24 17:01 gampleman

My vote is for both "List" and "return List a instead of Maybe (List a)"

miniBill avatar Jan 23 '24 17:01 miniBill

I'd advocate for providing both signatures:

  • getMany : Array Int -> Array a -> Array a
  • getManyList : List Int -> Array a -> List a

Like @miniBill , I'd tend to not wrap into a Maybe since:

  • the Nothing doesn't provide the list of erroneous indices
  • this is kind of consistent with Array.set
  • this is consistent with what we have in Numpy and similar array manipulation library (is it a valid argument?)

Having the two functions allows the developper to choose what fits most to its use case.

sebsheep avatar Feb 26 '24 20:02 sebsheep

Hm, so I just realized (thanks Copilot), that the list version is just:

List.filterMap (\index -> Array.get index array) indices

which is fairly trivial...

So perhaps this isn't needed. Closing for now (but if there is more demand we can reconsider).

gampleman avatar Jul 25 '24 21:07 gampleman