복붙노트

[SCALA] 목록에서 (codegeneration없이) 튜플을 만들 수있는 방법이 있습니까?

SCALA

목록에서 (codegeneration없이) 튜플을 만들 수있는 방법이 있습니까?

때때로 (예를 끓는 프레임 워크) 작은 컬렉션에서 튜플을 만들 필요가 있습니다.

def toTuple(list:List[Any]):scala.Product = ...

해결법

  1. ==============================

    1.당신은 앞까지 인수에 대응을 알고 끔찍한 끔찍한 해킹을하지 않으려면, 당신은이 작업을 수행 할 수 있습니다 :

    당신은 앞까지 인수에 대응을 알고 끔찍한 끔찍한 해킹을하지 않으려면, 당신은이 작업을 수행 할 수 있습니다 :

    def toTuple[A <: Object](as:List[A]):Product = {
      val tupleClass = Class.forName("scala.Tuple" + as.size)
      tupleClass.getConstructors.apply(0).newInstance(as:_*).asInstanceOf[Product]
    }
    toTuple: [A <: java.lang.Object](as: List[A])Product
    
    scala> toTuple(List("hello", "world"))
    res15: Product = (hello,world)
    
  2. ==============================

    2.이 쓸데없이 모호하기 때문에 당신은 정말 제품을 반환하기 위해 방법을 싶지 않아요. 당신이 튜플로 반환 된 객체를 사용할 수 있도록하려면, 당신은 그것의 인수에 대응 알고해야합니다. 그래서 당신이 할 수있는 것은 다른 arities에 대한 toTupleN 방법의 시리즈를 가지고있다. 편의를 위해, 당신은 서열에 다음과 같은 암시 적 방법을 추가 할 수 있습니다.

    이 쓸데없이 모호하기 때문에 당신은 정말 제품을 반환하기 위해 방법을 싶지 않아요. 당신이 튜플로 반환 된 객체를 사용할 수 있도록하려면, 당신은 그것의 인수에 대응 알고해야합니다. 그래서 당신이 할 수있는 것은 다른 arities에 대한 toTupleN 방법의 시리즈를 가지고있다. 편의를 위해, 당신은 서열에 다음과 같은 암시 적 방법을 추가 할 수 있습니다.

    이것은 어떤가요:

    class EnrichedWithToTuple[A](elements: Seq[A]) {
      def toTuple2 = elements match { case Seq(a, b) => (a, b) }
      def toTuple3 = elements match { case Seq(a, b, c) => (a, b, c) }
      def toTuple4 = elements match { case Seq(a, b, c, d) => (a, b, c, d) }
      def toTuple5 = elements match { case Seq(a, b, c, d, e) => (a, b, c, d, e) }
    }
    implicit def enrichWithToTuple[A](elements: Seq[A]) = new EnrichedWithToTuple(elements)
    

    그것을 같이 사용 :

    scala> List(1,2,3).toTuple3
    res0: (Int, Int, Int) = (1,2,3)
    
  3. ==============================

    3.경우 @dhg 관찰로, 당신은 당신이 여기에서 유용하게 뭔가를 할 수 앞까지 예상되는 인수에 대응을 알고있다. 당신이 쓸 수 볼품를 사용하여,

    경우 @dhg 관찰로, 당신은 당신이 여기에서 유용하게 뭔가를 할 수 앞까지 예상되는 인수에 대응을 알고있다. 당신이 쓸 수 볼품를 사용하여,

    scala> import shapeless._
    import shapeless._
    
    scala> import Traversables._
    import Traversables._
    
    scala> import Tuples._
    import Tuples._
    
    scala> List(1, 2, 3).toHList[Int :: Int :: Int :: HNil] map tupled
    res0: Option[(Int, Int, Int)] = Some((1,2,3))
    
  4. ==============================

    4.당신이 튜플하거나 제품을 원하십니까. 후자 때문에 :

    당신이 튜플하거나 제품을 원하십니까. 후자 때문에 :

    case class SeqProduct[A](elems: A*) {
      override def productArity: Int = elems.size
      override def productElement(i: Int) = elems(i)
    }
    
    SeqProduct(List(1, 2, 3): _*)
    
  5. ==============================

    5.@Kim Stebel의 생각을 바탕으로, 나는 서열에서 튜플을 생성하는 간단한 유틸리티를 썼습니다.

    @Kim Stebel의 생각을 바탕으로, 나는 서열에서 튜플을 생성하는 간단한 유틸리티를 썼습니다.

    import java.lang.reflect.Constructor
    
    /**
     * Created by Bowen Cai on 1/24/2015.
     */
    sealed trait Product0 extends Any with Product {
    
      def productArity = 0
      def productElement(n: Int) = throw new IllegalStateException("No element")
      def canEqual(that: Any) = false
    }
    object Tuple0 extends Product0 {
      override def toString() = "()"
    }
    
    case class SeqProduct(elems: Any*) extends Product {
      override def productArity: Int = elems.size
      override def productElement(i: Int) = elems(i)
      override def toString() = elems.addString(new StringBuilder(elems.size * 8 + 10), "(" , ",", ")").toString()
    }
    
    object Tuples {
    
      private[this] val ctors = {
        val ab = Array.newBuilder[Constructor[_]]
        for (i <- 1 to 22) {
          val tupleClass = Class.forName("scala.Tuple" + i)
          ab += tupleClass.getConstructors.apply(0)
        }
        ab.result()
      }
    
      def toTuple(elems: Seq[AnyRef]): Product = elems.length match {
        case 0 => Tuple0
        case size if size <= 22 =>
          ctors(size - 1).newInstance(elems: _*).asInstanceOf[Product]
        case size if size > 22 => new SeqProduct(elems: _*)
      }
    
    }
    
  6. from https://stackoverflow.com/questions/11305290/is-there-way-to-create-tuple-from-listwithout-codegeneration by cc-by-sa and MIT license