237 votes

Obtenir un élément dans la liste en Scala ?

Comment diable peut-on obtenir un élément à l'indice i à partir de la liste en scala ?

J'ai essayé get(i) et [i] - rien ne fonctionne. La recherche sur Google ne donne que la façon de "trouver" un élément dans la liste. Mais je connais déjà l'index de l'élément !

Voici le code qui ne compile pas :

def buildTree(data: List[Data2D]):Node ={
  if(data.length == 1){
      var point:Data2D = data[0]  //Nope - does not work

  }
  return null
}

En regardant le Liste des api ne m'aide pas, car mes yeux se croisent.

2 votes

Eh bien, il semble que données.tête a fonctionné... Mais cela ne me donne que le premier élément, pas n'importe lequel de la liste.

0 votes

Utilisez le Seq traits apply(index) si vous êtes sûr que l'indice n'est pas hors limites. _scala-lang.org/api/current/_

0 votes

Data.drop(i).head fonctionne pour accéder au i-ième élément

351voto

Rex Kerr Points 94401

Utilisez des parenthèses :

data(2)

Mais vous ne voulez pas vraiment faire cela avec des listes très souvent, car les listes liées prennent du temps à parcourir. Si vous voulez indexer dans une collection, utilisez Vector (immuable) ou ArrayBuffer (mutable) ou éventuellement Array (qui est juste un tableau Java, sauf qu'encore une fois vous l'indexez avec (i) au lieu de [i] ).

1 votes

En fait, je cherche quelque chose comme ArrayList en Java. Je suppose que l'immuabilité serait également acceptable.

1 votes

ArrayBuffer fonctionne comme ArrayList . Vector fonctionne comme une ArrayList --vous pouvez lire, mais vous ne pouvez pas écrire sans en créer un nouveau.

0 votes

Qu'en est-il d'une sous-liste ? Par exemple, en java, je fais "data.subList(0, index)".

147voto

adamnfish Points 2444

Il est plus sûr d'utiliser lift afin de pouvoir extraire la valeur si elle existe et échouer gracieusement si elle n'existe pas.

data.lift(2)

Ceci retournera None si la liste n'est pas assez longue pour fournir cet élément, et Some(value) si elle l'est.

scala> val l = List("a", "b", "c")
scala> l.lift(1)
Some("b")
scala> l.lift(5)
None

Lorsque vous effectuez une opération qui peut échouer de cette manière, il est bon d'utiliser une option et d'utiliser le système de types pour vous assurer que vous gérez le cas où l'élément n'existe pas.

Explication :

Cela fonctionne parce que la liste apply (ce qui se traduit par de simples parenthèses, par ex. l(index) ) est comme une fonction partielle qui est définie partout où la liste a un élément. Le site List.lift transforme la méthode partielle apply (une fonction qui n'est définie que pour certaines entrées) en une fonction normale (définie pour toute entrée) en enveloppant le résultat dans une option.

15 votes

L'ascenseur est magnifique. Je peux éviter les erreurs arrayIndexOutOfBound, sans vérifier la taille du tableau..

1 votes

L'opposé d'une fonction "partielle" (définie uniquement pour certaines entrées, pas toutes) est une fonction "totale" (définie pour toutes les entrées). Ce que vous appelez une fonction "normale" est techniquement appelé une fonction "totale". L'inférence apply como en l(1) [qui est en fait un raccourci pour l.apply(1) ] dans votre exemple est une fonction partielle. La fonction l.lift(1) est une fonction totale. Envelopper toute fonction partielle dans un Option (ou Try ou Either ) en fait une fonction totale.

9voto

B.Mr.W. Points 8215

Pourquoi des parenthèses ?

Voici la citation du livre programmation en scala .

Une autre idée importante illustrée par cet exemple vous permettra de comprendre pourquoi les tableaux sont accessibles avec des parenthèses en Scala. Scala a moins de cas particuliers que Java. Les tableaux sont simplement des instances de classes, comme toute autre classe en Scala. Lorsque vous appliquez des parenthèses entourant une ou plusieurs valeurs à une variable, Scala transformera le code en une invocation d'une méthode nommée apply sur cette variable. Ainsi, greetStrings(i) est transformé en greetStrings.apply(i). Ainsi, l'accès à un élément d'un tableau en Scala est simplement un appel de méthode comme un autre. Ce principe n'est pas limité aux tableaux : toute application d'un objet à certains arguments entre parenthèses sera transformée en un appel de méthode apply. Bien sûr, cela ne compilera que si ce type d'objet définit effectivement une méthode apply. Il ne s'agit donc pas d'un cas particulier, mais d'une règle générale.

Voici quelques exemples de la façon de tirer un certain élément (le premier élément dans ce cas) en utilisant le style de programmation fonctionnelle.

  // Create a multdimension Array 
  scala> val a = Array.ofDim[String](2, 3)
  a: Array[Array[String]] = Array(Array(null, null, null), Array(null, null, null))
  scala> a(0) = Array("1","2","3")
  scala> a(1) = Array("4", "5", "6")
  scala> a
  Array[Array[String]] = Array(Array(1, 2, 3), Array(4, 5, 6))

  // 1. paratheses
  scala> a.map(_(0))
  Array[String] = Array(1, 4)
  // 2. apply
  scala> a.map(_.apply(0))
  Array[String] = Array(1, 4)
  // 3. function literal
  scala> a.map(a => a(0))
  Array[String] = Array(1, 4)
  // 4. lift
  scala> a.map(_.lift(0))
  Array[Option[String]] = Array(Some(1), Some(4))
  // 5. head or last 
  scala> a.map(_.head)
  Array[String] = Array(1, 4)

3voto

Veuillez utiliser les parenthèses () pour accéder aux éléments de la liste. nom_de_la_liste(index)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X