Pergunta

Se eu tenho algo como um List[Option[A]] e eu quero converter isso em um List[A], a maneira padrão é usar flatMap:

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatMap( o => o)
res0: List[java.lang.String] = List(Hello, World)

Agora o => o é apenas uma função de identidade. Eu teria pensado que haveria uma maneira de fazer:

l.flatMap(Identity) //return a List[String]

No entanto, não consigo fazer isso funcionar, pois você não pode gerar um object. Eu tentei algumas coisas sem sucesso; Alguém tem algo assim para funcionar?

Foi útil?

Solução

Há uma identidade função em predef.

l flatMap identity[Option[String]]

> List[String] = List(Hello, World)

A para a expresso é melhor, suponho:

for(x <- l; y <- x) yield y

Editar:

Tentei descobrir por que o parâmetro de tipo (opção [string]) é necessário. O problema parece ser a conversão do tipo da opção [t] para iterable [t].

Se você definir a função de identidade como:

l.flatMap( x => Option.option2Iterable(identity(x)))

o parâmetro de tipo pode ser omitido.

Outras dicas

Fwiw, no scala 2.8 você apenas liga flatten nele. Thomas Ele abordou principalmente o Scala 2.7. Ele só perdeu uma maneira alternativa de usar essa identidade:

l.flatMap[String](identity)

No entanto, não funcionará com a notação do operador (parece que a notação do operador não aceita parâmetros de tipo, o que é bom saber).

Você pode também ligar flatten em Scala 2.7 (em um List, pelo menos), mas não será capaz de fazer nada sem um tipo. No entanto, isso funciona:

l.flatten[String]

Você pode apenas dar uma ajudinha para o tipo Inferencer:

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatten[String]
res0: List[String] = List(Hello, World)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top