2008-09-10 38 views
16

Recientemente he estado trabajando en un proyecto para principiantes en Scala, y tengo una pregunta para principiantes sobre las listas de Scala.Devolución de un elemento de una lista en Scala

Supongo que tengo una lista de tuplas (List[Tuple2[String, String]], por ejemplo). ¿Hay algún método de conveniencia para devolver la primera ocurrencia de una tupla especificada de la Lista, o es necesario recorrer la lista a mano?

Respuesta

6

Puede intentar utilizando find. (Actualización de la ubicación de scala-doc de find)

2

Si está aprendiendo scala, eche un vistazo al rasgo Seq. Proporciona la base para gran parte de la bondad funcional de Scala.

+0

El enlace está roto. – ctford

+0

El enlace funciona. – akauppi

13
 
scala> val list = List(("A", "B", 1), ("C", "D", 1), ("E", "F", 1), ("C", "D", 2), ("G", "H", 1)) 
list: List[(java.lang.String, java.lang.String, Int)] = List((A,B,1), (C,D,1), (E,F,1), (C,D,2), (G,H,1)) 

scala> list find {e => e._1 == "C" && e._2 == "D"} 
res0: Option[(java.lang.String, java.lang.String, Int)] = Some((C,D,1)) 
+2

¿Es posible devolver algo ((C, D, 1)) pero (C, D, 1)? Quiero decir de la misma manera si quisiera usar list (1). – grass

+2

@grass ¿Cuál debería ser el valor de retorno si el triple '(C, D, 1)' no se encuentra en la lista? –

+1

Ninguna o excepción o conjunto vacío. Sería genial si hubiera una manera de personalizar el valor de retorno si no se encuentra el triple (excepto escribir mi propio método de find()). – grass

3

Como se mencionó en un comentario anterior, find es probablemente la forma más sencilla de hacerlo. En realidad, hay tres métodos diferentes de "búsqueda lineal" en las colecciones de Scala, cada uno con un valor ligeramente diferente. Cuál de las aplicaciones depende de para qué necesita los datos. Por ejemplo, ¿necesita un índice, o simplemente necesita un booleano true/false?

+0

¿Podría dar más información sobre estos métodos de "búsqueda lineal"? Estoy buscando obtener el índice de una tupla (teniendo solo una parte de la tupla) – krookedking

+0

en realidad encontré lo que estaba buscando: '.zipWithIndex.collect {case (" partOfTuple ", _, i) => i } ' – krookedking

1

También podría hacer esto, que no requiere conocer los nombres de los campos en la clase Tuple2 - que utiliza la coincidencia de patrones en su lugar:

list find { case (x,y,_) => x == "C" && y == "D" } 

"hallazgo" es bueno cuando se sabe que sólo necesita un ; si usted quiere encontrar todos los elementos coincidentes se podría utilizar ya sea "filtro" o el azúcar equivalente para la comprensión:

for ((x,y,z) <- list if x == "C" && y == "D") yield (x,y,z) 
+1

Su segundo ejemplo parece funcionar mucho más como' filter', es decir, devolverá * todos * elementos que coincidan con la propiedad, no el primero como el autor de la pregunta lo quiere. –

1

Aquí está el código que puede ayudarle.

Tuve un caso similar, con una colección de entradas de la clase base (aquí, A) de la que quería encontrar un determinado nodo de la clase derivada, en su caso (aquí, B).

class A 

case class B(val name: String) extends A 

object TestX extends App { 
    val states: List[A] = List(B("aa"), new A, B("ccc")) 

    def findByName(name: String): Option[B] = { 
    states.find{ 
     case x: B if x.name == name => return Some(x) 
     case _ => false 
    } 
    None 
    } 

    println(findByName("ccc")) // "Some(B(ccc))" 
} 

La parte importante aquí (para mi aplicación) es que no vuelve findByNameOption[A] pero Option[B].

En su lugar, puede modificar fácilmente el comportamiento para devolver B y lanzar una excepción si no se encontró ninguna. Espero que esto ayude.

1

Considérese collectFirst que entrega Some[(String,String)] para la primera tupla coincidente o None de otra manera, por ejemplo como sigue,

xs collectFirst { case [email protected](a,_) if a == "existing" => t } 
Some((existing,str)) 

scala> xs collectFirst { case [email protected](a,_) if a == "nonExisting" => t } 
None 

Usando @ ligamos el valor de la tupla a t de modo que una tupla coincidente todo puede ser recogido .

Cuestiones relacionadas