scala combina colecciones como colecciones 1d
Me gustaría tener funciones como el lenguaje R c
función :
#R
print(c(c(1,2,3),2,3,c(1,2)))
> c(1,2,3,2,3,1,2)
mi solución es
trait SeqMagnet[A] {
type Result = Seq[A]
def apply(): Result
}
object SeqMagnet {
implicit class fromString(x: String) extends SeqMagnet[String] {
override type Result = Seq[String]
override def apply(): Result = Seq(x)
}
implicit class fromInt(x: Int) extends SeqMagnet[Int] {
override type Result = Seq[Int]
override def apply(): Result = Seq(x)
}
implicit class fromDouble(x: Double) extends SeqMagnet[Double] {
override type Result = Seq[Double]
override def apply(): Result = Seq(x)
}
implicit class fromSeq(x: TraversableOnce[_]) extends SeqMagnet[_] {
override type Result = Seq[_]
override def apply(): Result = x.toSeq
}
}
object Combine {
def toSeq(magnet: SeqMagnet[_]) = magnet()
def c(any: SeqMagnet[_]*) = {
any.map(toSeq(_)).flatten
}
}
pero lo entiendo seq[Any]
de esta función,
y algún error para fromSeq
CLASE
mi espera es así
# pseudo-code
def c[A](A( or A collections)*):Seq[A]
----
input: Int Seq(1,2,3) ,seq(4,5)
output: Seq(1,2,3,4,5):Seq[Int]
----
input: String Seq("a",b"), "d",seq("c","e")
output: Seq("a","b","d","c","e")
mi versión scala es 2.11
Pregunta hecha hace 3 años, 4 meses, 27 días - Por debugduke
3 Respuestas:
-
Necesitas usar un parámetro tipoComo el que apareces en tu pseudo código.
import scala.language.implicitConversions object c { private trait CMagnet[+A] { def get: Seq[A] } private object CMagnet { implicit def fromPlainValue[A](a: A): CMagnet[A] = new CMagnet[A] { def get: Seq[A] = a :: Nil } implicit def fromSeq[A](seq: Seq[A]): CMagnet[A] = new CMagnet[A] { def get: Seq[A] = seq } } def apply[A](args: CMagnet[A]*): Seq[A] = args.flatMap(_.get) }
Y puedes usarlo así:
val seq = Seq("A", "B") val result = c(seq, "C", "D", Seq("E", "F", "G"), "H") // result: Seq[String] = ArraySeq(A, B, C, D, E, F, G, H)
O así:
val seq = c("A", "B") val result = c(seq, "C", "D", c("E", c("F", "G")), "H") // result: Seq[String] = ArraySeq(A, B, C, D, E, F, G, H)
La razón por la que dije que sería mejor evitar esto es que necesita mucho (Avanzado) código a algo que uno puede pensar no es tan útil, pero si lo necesitas allí vas.
Puedes ver el código en funcionamiento Aquí..
Respondida el Dec 19, 2020 a las 03:37 - por techwizkid
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando se debe a que estás utilizando la clase
_
en tufromSeq
implicit class, lo cual hace que el tipo sea inferido comoAny
. Para solucionar este problema, puedes parametrizarfromSeq
con un tipo concreto y luego especificar ese tipo al utilizarfromSeq
. Aquí te dejo una forma de corregir tu código:scala trait SeqMagnet[A] { type Result = Seq[A] def apply(): Result } object SeqMagnet { implicit class fromString(x: String) extends SeqMagnet[String] { override type Result = Seq[String] override def apply(): Result = Seq(x) } implicit class fromInt(x: Int) extends SeqMagnet[Int] { override type Result = Seq[Int] override def apply(): Result = Seq(x) } implicit class fromDouble(x: Double) extends SeqMagnet[Double] { override type Result = Seq[Double] override def apply(): Result = Seq(x) } implicit class fromSeqA extends SeqMagnet[A] { override type Result = Seq[A] override def apply(): Result = x.toSeq } } object Combine { def toSeqA = magnet() def cA = { any.map(toSeq(_)).flatten } }
Con estos cambios, la clase
fromSeq
ahora está parametrizada con un tipoA
, lo que te permitirá usarla correctamente con valores concretos al llamar afromSeq
.Prueba nuevamente tu función
c
con los ejemplos que mencionas y deberías obtener el resultado esperado.Respondida el Dec 20, 2020 a las 03:37 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error que estás encontrando en tu código Scala se debe a que el método
apply
en la clasefromSeq
no devuelve unSeq[_]
, sino unSeq[Any]
. Para solucionar este problema, podemos hacer que el métodoapply
devuelva unSeq[A]
, dondeA
es el tipo genérico de la claseSeqMagnet
.Aquí tienes el código corregido:
scala trait SeqMagnet[A] { type Result = Seq[A] def apply(): Result } object SeqMagnet { implicit class fromString(x: String) extends SeqMagnet[String] { override type Result = Seq[String] override def apply(): Result = Seq(x) } implicit class fromInt(x: Int) extends SeqMagnet[Int] { override type Result = Seq[Int] override def apply(): Result = Seq(x) } implicit class fromDouble(x: Double) extends SeqMagnet[Double] { override type Result = Seq[Double] override def apply(): Result = Seq(x) } implicit class fromSeqA extends SeqMagnet[A] { override type Result = Seq[A] override def apply(): Result = x } } object Combine { def toSeq(magnet: SeqMagnet[_]) = magnet() def cA: Seq[A] = { any.map(toSeq(_)).flatten } }
Con esta corrección, el método
c
devolverá unSeq[A]
, dondeA
es el tipo genérico de los elementos de las colecciones de entrada.Por ejemplo, para combinar una secuencia de enteros y una secuencia de cadenas, puedes utilizar el método
c
de la siguiente manera:scala val intSeq = Seq(1, 2, 3) val stringSeq = Seq("a", "b", "c") val combinedSeq = Combine.c(intSeq, stringSeq) combinedSeq.foreach(println)
Esto imprimirá la siguiente salida:
1 2 3 a b c
Respondida el Dec 20, 2020 a las 03:50 - por Gemini
Votos positivos: 0 | Votos negativos: 0