How do I return multiple elements from a list given their indices?

Let's say I have a list. If I want to return something in the index of this list, I can just pass the index val, index. Thus.

val list = List(1, 2, 3) 
list(0) //Int = 1

      

But what if I want elements from multiple indices in this list? I want to be able to do this ... list(0, 1)

and get a set of elements at those indices.

It's insanely simple in Ruby. Anyone have any suggestions?

+3


source to share


3 answers


You can flip the logic so that for each index, you get the index, you get the element at that index. Since you are using the apply

on method List

, there are several shorthand expressions for this logic:

val indices = List(0, 1)
indices.map(index => list.apply(index))
indices.map(index => list(index))
indices.map(list(_))
indices.map(list)
indices map list

      

It's worth noting that since this is all maps

on indices

, the resulting collection will generally be of the same type as indices

, rather than List

:

val list = Array(1, 2, 3)
val indices = List(0, 1)
indices map list //List(1, 2), instead of Array(1, 2)

      

This might be an unwanted property here. One solution to this is to use breakOut

(in scala.collection

):

val newList: Array[Int] = indices.map(list)(breakOut)

      

You can read more about breakOut here . The following solutions also support collection type List

when possible, performing operations on List

instead indeces

:



If you are looking for a contiguous range of a list, you can use slice

:

list.slice(1, 2) //List(2)

      

You can also use drop

and take

(and versions dropRight

, takeRight

) for a similar effect:

list.drop(1).take(1)

      

For more complex versions of this type of filtering, you might be interested in a method zipWithIndex

that allows you to express arbitrary logic by index:

list.zipWithIndex.collect { 
    case(el, index) if indices.contains(index) /* any other logic */ => el 
}

      

+9


source


The answer from @Ben is in place.

However, if you want to use the descriptive syntax, list(0, 1)

then Scala allows you to do so through implicit conversions:

implicit class MultiIndexList[A](list: List[A]){
    def apply(indices: Int *) = indices.map(list)
}

      



Assuming you are working on the REPL:

val list = List(1,2,3)

list(1,2)
res1: Seq[Int] = ArrayBuffer(2, 3)

list(0,2)
res2: Seq[Int] = ArrayBuffer(1, 3)

      

+3


source


If you're looking for the Ruby Array#slice

(aka Array#[]

) equivalent , there are two:

There is also no Ruby equivalent Array#values_at

.

+1


source







All Articles