2010-08-31 74 views
27

La tarea es buscar un valor de campo específico (por su número en línea) por un valor de campo clave en un archivo CSV simple (solo comas como separadores, sin comillas circundantes, nunca una coma dentro de un campo), teniendo un encabezado en su primera línea.En Scala, ¿cómo leer un archivo CSV simple con un encabezado en su primera línea?

uynhjl usuario ha dado un ejemplo (pero con un carácter diferente como separador):

 

val src = Source.fromFile("/etc/passwd") 
val iter = src.getLines().map(_.split(":")) 
// print the uid for Guest 
iter.find(_(0) == "Guest") foreach (a => println(a(2))) 
// the rest of iter is not processed 
src.close() 
 

la pregunta en este caso es cómo saltar una línea de cabecera de análisis?

+0

Acabo de escribir una pregunta y una respuesta exhaustiva que cubra tanto analizar la entrada como componer la salida para un archivo CSV. Se encuentra aquí: http://stackoverflow.com/a/32488453/501113 – chaotic3quilibrium

Respuesta

24

Usted sólo puede utilizar drop:

val iter = src.getLines().drop(1).map(_.split(":")) 

Desde el documentation:

def drop (n: Int) : Iterator[A]: Avances este iterador allá de las primeras n elementos, o la longitud de la iterador, lo que sea más pequeño.

12

Aquí hay un CSV reader in Scala. Yikes.

Como alternativa, puede buscar un CSV reader in Java y llamarlo desde Scala.

Analizar correctamente los archivos CSV no es una cuestión trivial. Frases de escape, para empezar.

+1

He visto esto, pero parece demasiado complejo para mi caso simple. No necesito todas esas expresiones regulares ya que mis archivos son muy simples. – Ivan

+0

Acabo de publicar una solución mucho más simple (que se puede copiar/pegar fácilmente en el contexto de codificación local) en esta respuesta de StackOverflow: http://stackoverflow.com/a/32488453/501113 – chaotic3quilibrium

+0

Esto debería ser un comentario en el mejor de los casos , ya que no aborda la pregunta (cómo omitir una fila). –

2

Primero leí la línea de cabecera usando take(1), y luego el resto de líneas ya están en src iterador. Esto funciona bien para mi.

val src = Source.fromFile(f).getLines 

// assuming first line is a header 
val headerLine = src.take(1).next 

// processing remaining lines 
for(l <- src) { 
    // split line by comma and process them 
    l.split(",").map { c => 
     // your logic here 
    } 
} 
+0

El problema con 'split (", ")' es que cuando te encuentras con una cadena como '" This, that "', también la divide aunque sea parte de un solo punto. –

+0

Acabo de abordar el muy común y erróneo consejo "use split (", ") en mi respuesta integral a una pregunta CSV aquí: http://stackoverflow.com/a/32488453/501113 – chaotic3quilibrium

+1

La pregunta dice' simple CSV'. Si CSV no es simple, siempre es mejor para nosotros una biblioteca CSV dedicada. – tuxdna

Cuestiones relacionadas