복붙노트

[SCALA] 튜플에 스칼라 목록을 변환?

SCALA

튜플에 스칼라 목록을 변환?

어떻게 크기 3의 튜플에 (예를 들어) 3 개 요소 목록을 변환 할 수 있습니까?

예를 들어, 내가 발 X = 목록이 있다고 가정 해 봅시다 (1, 2, 3) 나는이 점을 변환 할 (1, 2, 3). 이걸 어떻게 할 수 있습니까?

해결법

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

    1.당신은 보증 된 방법으로이 작업을 수행 할 수 없습니다. 왜? 때문에 일반적으로 우리는 런타임 때까지 목록의 길이를 알 수 없다. 그러나 튜플의 "길이"의 형식으로 인코딩하고, 따라서 컴파일시에 알려 져야한다. 예를 들어, (1, 'A', 참)의 Tuple3 [INT, 숯, 부울] 설탕 인 유형 (INT, 숯, 불리언)을 갖는다. 이유 튜플이 제한들이 비 균일 유형을 처리 할 수 ​​있어야한다는 것입니다 있습니다.

    당신은 보증 된 방법으로이 작업을 수행 할 수 없습니다. 왜? 때문에 일반적으로 우리는 런타임 때까지 목록의 길이를 알 수 없다. 그러나 튜플의 "길이"의 형식으로 인코딩하고, 따라서 컴파일시에 알려 져야한다. 예를 들어, (1, 'A', 참)의 Tuple3 [INT, 숯, 부울] 설탕 인 유형 (INT, 숯, 불리언)을 갖는다. 이유 튜플이 제한들이 비 균일 유형을 처리 할 수 ​​있어야한다는 것입니다 있습니다.

  2. ==============================

    2.당신은 스칼라 추출기 및 패턴 매칭 (링크)를 사용하여 수행 할 수 있습니다

    당신은 스칼라 추출기 및 패턴 매칭 (링크)를 사용하여 수행 할 수 있습니다

    val x = List(1, 2, 3)
    
    val t = x match {
      case List(a, b, c) => (a, b, c)
    }
    

    어떤 튜플을 반환

    t: (Int, Int, Int) = (1,2,3)
    

    또한, 당신은 목록의 크기에 대해 확실하지 와일드 카드 연산자를 사용할 수 있습니다

    val t = x match {
      case List(a, b, c, _*) => (a, b, c)
    }
    
  3. ==============================

    3.엉성한 사용 예 :

    엉성한 사용 예 :

    import shapeless._
    import syntax.std.traversable._
    val x = List(1, 2, 3)
    val xHList = x.toHList[Int::Int::Int::HNil]
    val t = xHList.get.tupled
    

    참고 : 컴파일러는 HList의 목록을 변환하는 몇 가지 유형의 정보를 필요로하는 당신이 toHList 방법에 유형의 정보를 전달해야하는 이유

  4. ==============================

    4.2.0 볼품없는 몇 가지 구문을 변경했습니다. 다음은 볼품 사용하여 업데이트 된 솔루션이다.

    2.0 볼품없는 몇 가지 구문을 변경했습니다. 다음은 볼품 사용하여 업데이트 된 솔루션이다.

    import shapeless._
    import HList._
    import syntax.std.traversable._
    
    val x = List(1, 2, 3)
    val y = x.toHList[Int::Int::Int::HNil]
    val z = y.get.tupled
    

    주요 문제는 .toHList의 유형을 미리 지정해야한다는 것. 튜플은 자신의 arity에 제한되어 있기 때문에 더 일반적으로, 소프트웨어의 디자인이 더 나은 다른 솔루션에 의해 제공 될 수 있습니다.

    당신이 정적으로 목록을 작성하는 경우 그러나, 또한 무형의 사용, 이와 같은 솔루션을 고려한다. 여기, 우리가 직접 HList를 만들고 유형은 컴파일시에 사용할 수 있습니다. HList 모두 목록 및 튜플 유형의 기능을 가지고 있음을 기억하십시오. 즉 그것은 튜플과 같은 다른 유형의 요소를 가질 수 있고, 표준 컬렉션과 같은 다른 동작들 사이에 매핑 될 수있다. HLists 당신이 새로운 경우 천천히 밟아하지만 익숙해 약간의 시간이 걸릴.

    scala> import shapeless._
    import shapeless._
    
    scala> import HList._
    import HList._
    
    scala>   val hlist = "z" :: 6 :: "b" :: true :: HNil
    hlist: shapeless.::[String,shapeless.::[Int,shapeless.::[String,shapeless.::[Boolean,shapeless.HNil]]]] = z :: 6 :: b :: true :: HNil
    
    scala>   val tup = hlist.tupled
    tup: (String, Int, String, Boolean) = (z,6,b,true)
    
    scala> tup
    res0: (String, Int, String, Boolean) = (z,6,b,true)
    
  5. ==============================

    5.단순성과 길이의 목록에 대한되지에도 불구하고, 그것은 안전 입력하고 대부분의 경우 대답입니다 :

    단순성과 길이의 목록에 대한되지에도 불구하고, 그것은 안전 입력하고 대부분의 경우 대답입니다 :

    val list = List('a','b')
    val tuple = list(0) -> list(1)
    
    val list = List('a','b','c')
    val tuple = (list(0), list(1), list(2))
    

    이 목록의 이름을 지정하거나 그것을 반복하지 않으려는 경우 또 다른 가능성, (나는 누군가가 서열 번호 / 헤드 부분을 피할 수있는 방법을 보여줄 수 있기를 바랍니다)

    val tuple = Seq(List('a','b')).map(tup => tup(0) -> tup(1)).head
    val tuple = Seq(List('a','b','c')).map(tup => (tup(0), tup(1), tup(2))).head
    
  6. ==============================

    6.FWIW, 내가 필드의 숫자를 초기화하는 튜플을 원하고 튜플 할당의 문법 설탕을 사용하고 싶었다. EG :

    FWIW, 내가 필드의 숫자를 초기화하는 튜플을 원하고 튜플 할당의 문법 설탕을 사용하고 싶었다. EG :

    val (c1, c2, c3) = listToTuple(myList)
    

    너무 목록의 내용을 할당하기위한 문법 설탕이 있다고 밝혀 ...

    val c1 :: c2 :: c3 :: Nil = myList
    

    그래서 튜플 필요 동일한 문제가있어합니다.

  7. ==============================

    7.당신은 형식 안전한 방법으로이 작업을 수행 할 수 없습니다. 스칼라,리스트는 특정 유형의 소자의 임의의 길이의 시퀀스이다. 지금까지 타입 시스템이 알고있는대로, X는 임의의 길이의 목록이 될 수 있습니다.

    당신은 형식 안전한 방법으로이 작업을 수행 할 수 없습니다. 스칼라,리스트는 특정 유형의 소자의 임의의 길이의 시퀀스이다. 지금까지 타입 시스템이 알고있는대로, X는 임의의 길이의 목록이 될 수 있습니다.

    반면, 튜플의 인수에 대응이 컴파일시에 알려 져야한다. 그것은 튜플 타입 X를 할당 할 수 있도록 타입 시스템의 안전 보장을 위반하는 것입니다.

    사실, 기술적 인 이유로, 스칼라 튜플 (22 개) 요소로 제한하지 않지만, 한계는 더 이상 2.11의 경우 클래스 제한 2.11 https://github.com/scala/scala/pull/2305에서 해제 된 존재했다

    수동 소자 (22)까지의리스트를 변환하고, 큰 목록에 대한 예외를 발생하는 기능을 코딩하는 것이 가능하다. 스칼라의 템플릿 지원, 곧 기능이 더 간결하게 만들 것입니다. 하지만이 못생긴 해킹 것이다.

  8. ==============================

    8.이것은 또한 적은 보일러는 크기의 사용과 무형 수행 할 수 있습니다 :

    이것은 또한 적은 보일러는 크기의 사용과 무형 수행 할 수 있습니다 :

    scala> import shapeless._
    scala> import shapeless.syntax.sized._
    
    scala> val x = List(1, 2, 3)
    x: List[Int] = List(1, 2, 3)
    
    scala> x.sized(3).map(_.tupled)
    res1: Option[(Int, Int, Int)] = Some((1,2,3))
    

    튜플의 크기가 잘못된 경우가 없음을 얻을 수 없지만, 튜플의 크기는 (shapeless.Nat로 변환 가능합니다) 리터럴 또는 최종 발해야합니다 : 그것은 입력-안전합니다.

  9. ==============================

    9.당신은 당신의는 list.size <23을 사용하는 것이 매우 확신하는 경우 :

    당신은 당신의는 list.size <23을 사용하는 것이 매우 확신하는 경우 :

    def listToTuple[A <: Object](list:List[A]):Product = {
      val class = Class.forName("scala.Tuple" + list.size)
      class.getConstructors.apply(0).newInstance(list:_*).asInstanceOf[Product]
    }
    listToTuple: [A <: java.lang.Object](list: List[A])Product
    
    scala> listToTuple(List("Scala", "Smart"))
    res15: Product = (Scala,Smart)
    
  10. ==============================

    10.지금까지 당신이 유형을 가지고 :

    지금까지 당신이 유형을 가지고 :

    val x: List[Int] = List(1, 2, 3)
    
    def doSomething(a:Int *)
    
    doSomething(x:_*)
    
  11. ==============================

    11.2015 게시 할 수 있습니다. 톰 크로켓의 응답을 더 명확히 할 경우, 여기에 실제 예입니다.

    2015 게시 할 수 있습니다. 톰 크로켓의 응답을 더 명확히 할 경우, 여기에 실제 예입니다.

    처음에는 그것에 대해 혼동되었다. 나는 그냥 튜플 할 수 파이썬에서 온 있기 때문에 (목록 (1,2,3)). 그것은 스칼라 언어의 짧은가요? (대답은 - 그것은 스칼라 파이썬에 대해 아니다, 그것은 정적 형과 동적 형에 관하여이다.)

    그의 날 스칼라는이 작업을 수행 할 수없는 이유 요점을 찾기 위해 노력됩니다.

    다음의 코드는, 형태 보증 toTupleN 입력 불안전 toTuple을 갖는 toTuple 방법을 구현한다.

    toTuple 방법은 컴파일시에 유형 길이 정보, 즉 없으며, 실행시 유형 길이 정보를 얻을 수 있기 때문에 반환 형식 (각 위치에서 어떤 유형, 그리고 어떤 길이 참으로 아주 파이썬의 튜플처럼없는 제품입니다 유형). 그 방법은 유형이 불일치하거나 IndexOutOfBoundException 같은 오류를 런타임에 proned된다. (그래서 파이썬의 편리한 목록 - 투 - 튜플 무료 점심되지 않습니다.)

    반대로, 그것은 toTupleN이 컴파일시에 안전하게 제공되는 길이 정보 사용자입니다.

    implicit class EnrichedWithToTuple[A](elements: Seq[A]) {
      def toTuple: Product = elements.length match {
        case 2 => toTuple2
        case 3 => toTuple3
      }
      def toTuple2 = elements match {case Seq(a, b) => (a, b) }
      def toTuple3 = elements match {case Seq(a, b, c) => (a, b, c) }
    }
    
    val product = List(1, 2, 3).toTuple
    product.productElement(5) //runtime IndexOutOfBoundException, Bad ! 
    
    val tuple = List(1, 2, 3).toTuple3
    tuple._5 //compiler error, Good!
    
  12. ==============================

    12.당신은이 작업을 수행 할 수 있습니다

    당신은이 작업을 수행 할 수 있습니다

  13. ==============================

    13.패턴 매칭 사용 :

    패턴 매칭 사용 :

    브로 intTuple 목록 = (1,2,3) {경우 매치리스트 (A, B, C) => (A, B, C)}

  14. from https://stackoverflow.com/questions/14722860/convert-a-scala-list-to-a-tuple by cc-by-sa and MIT license