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 tu fromSeq implicit class, lo cual hace que el tipo sea inferido como Any. Para solucionar este problema, puedes parametrizar fromSeq con un tipo concreto y luego especificar ese tipo al utilizar fromSeq. 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 tipo A, lo que te permitirá usarla correctamente con valores concretos al llamar a fromSeq.

    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 clase fromSeq no devuelve un Seq[_], sino un Seq[Any]. Para solucionar este problema, podemos hacer que el método apply devuelva un Seq[A], donde A es el tipo genérico de la clase SeqMagnet.

    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á un Seq[A], donde A 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