J'ai List[Int]
dans Scala
. La liste est List(1,2,3,4,5,6,7,8,9,10)
. Je veux filter
la liste afin qu'elle ne comporte que des nombres pairs. Et je veux multiplier les nombres avec 2. Est-ce possible?
J'espère avoir clairement expliqué la question. Si vous avez des questions, n'hésitez pas à demander. Merci d'avance.
Comme je le dis dans mon commentaire, collect
devrait faire ce que vous voulez:
list.collect{
case x if x % 2 == 0 => x*2
}
La méthode collect
vous permet à la fois de spécifier un critère sur les éléments correspondants (filter
) et de modifier les valeurs qui correspondent (map
).
Et comme @TravisBrown l'a suggéré, vous pouvez également utiliser flatMap
, en particulier dans des situations où la condition est plus complexe et ne convient pas comme condition de garde. Quelque chose comme ça pour votre exemple:
list.flatMap{
case x if x % 2 == 0 => Some(x*2)
case x => None
}
A pour la compréhension (qui se déroule en interne dans une combinaison de map
et withFilter
) comme suit,
for (x <- xs if x % 2 == 0) yield x*2
À savoir
xs.withFilter(x => x % 2 == 0).map(x => x*2)
Comme @cmbaxter l'a dit, collect convient parfaitement à vos besoins. L'autre bonne chose à propos de collect, c'est qu'il calcule le type résultant si vous filtrez par classe:
scala> trait X
// defined trait X
scala> class Foo extends X
// defined class Foo
scala> class Bar extends X
// defined class Bar
scala> val xs = List(new Foo, new Bar, new Foo, new Bar)
// xs: List[X] = List(Foo@4cfa8227, Bar@78226c36, Foo@3f685162, Bar@11f406f8)
scala> xs.collect { case x: Foo => x }
// res1: List[Foo] = List(Foo@4cfa8227, Foo@3f685162)
Au pair, le filtre ne peut pas être aussi intelligent (voir List[Foo]
vs List[X]
):
scala> xs.filter { case x: Foo => true; case _ => false }
// res3: List[X] = List(Foo@4cfa8227, Foo@3f685162)
Que diriez-vous d'un bon vieux pli?
xs.foldLeft(List[Y]()) { (ys, x) =>
val z = calculateSomethingOnX(x)
if (someConditionOnZ(z))
Y(x, z) :: ys
else
ys
}
J'ai tendance à aimer l'approche du filtre.
val list1 = List(1,2,3,4,5,6,7,8,9,10)
list1.filter(x => x%2 == 0).map(_*2)
Cela devrait faire le travail pour vous:
Filtrez d'abord lorsque la condition est p % 2 == 0
(pour obtenir uniquement des nombres pairs).
Et utilisez ensuite map
pour multiplier ces nombres pairs par 2.
var myList = List(1,2,3,4,5,6,7,8,9,10).filter(p => p % 2 == 0).map(p => {p*2})