복붙노트

[SCALA] 간단한 경우 클래스에 대한 주문을 정의하기 쉬운 관용적 방법

SCALA

간단한 경우 클래스에 대한 주문을 정의하기 쉬운 관용적 방법

나는 간단한 스칼라의 경우 클래스 인스턴스의 목록을하고 난 list.sorted 사용하여 예측, 사전 편찬 순서로 인쇄 할 만받을 "어떤 암시 주문이 정의되지 ...".

경우 클래스에 대한 사전 편찬 순서를 제공하는 암시 적 존재인가?

혼합 된 위해 사전 편찬 주문의 경우 클래스로 간단한 관용의 방법이 있습니까?

scala> case class A(tag:String, load:Int)
scala> val l = List(A("words",50),A("article",2),A("lines",7))

scala> l.sorted.foreach(println)
<console>:11: error: No implicit Ordering defined for A.
          l.sorted.foreach(println)
            ^

나는 '해킹'행복하지 않다 :

scala> l.map(_.toString).sorted.foreach(println)
A(article,2)
A(lines,7)
A(words,50)

해결법

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

    1.이 명확하고 간결하고 정확으로 내 개인 좋아하는 방법은 튜플의 제공 암시 순서를 사용하는 것입니다 :

    이 명확하고 간결하고 정확으로 내 개인 좋아하는 방법은 튜플의 제공 암시 순서를 사용하는 것입니다 :

    case class A(tag: String, load: Int) extends Ordered[A] {
      // Required as of Scala 2.11 for reasons unknown - the companion to Ordered
      // should already be in implicit scope
      import scala.math.Ordered.orderingToOrdered
    
      def compare(that: A): Int = (this.tag, this.load) compare (that.tag, that.load)
    }
    

    이 작품은 모든 클래스에 대한 범위에 정렬 된 [T]로 주문에서 주문을 정의의 동반자 암시 적 변환 [T]를 순서가 구현 때문이다. 튜플 암시 적 순서화의 존재는 정렬에 [...] [TupleN [...] 암시 주문 [TN]를 제공하는 모든 요소에 대해 존재 TupleN에서 전환을 가능하게 T1, ..., 튜플의 TN 어느 그것은 더 주문과 데이터 형식을 정렬 할 말이 없기 때문에 항상 사건이어야한다.

    튜플에 대한 암시 적 순서는 당신의 복합 정렬 키와 관련된 모든 정렬 시나리오에 대한 이동-이다 :

    as.sortBy(a => (a.tag, a.load))
    

    이 대답은 인기가 입증 된 바와 같이 나는 다음을 닮은 솔루션은 어떤 상황에서 엔터프라이즈 급 ™ 간주 될 수 있음을 지적, 그것을 확장하고 싶습니다 :

    case class Employee(id: Int, firstName: String, lastName: String)
    
    object Employee {
      // Note that because `Ordering[A]` is not contravariant, the declaration
      // must be type-parametrized in the event that you want the implicit
      // ordering to apply to subclasses of `Employee`.
      implicit def orderingByName[A <: Employee]: Ordering[A] =
        Ordering.by(e => (e.lastName, e.firstName))
    
      val orderingById: Ordering[Employee] = Ordering.by(e => e.id)
    }
    

    것이다 일종의 ID로 es.sorted SeqLike [사원], () 종류의 이름으로, 그리고 (Employee.orderingById)를 es.sorted됩니다 감안할 때 말이지. 이것은 몇 가지 장점이 있습니다 :

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

    2.

    object A {
      implicit val ord = Ordering.by(unapply)
    }
    

    이것은 A가 변경 될 때마다 자동으로 업데이트된다는 이점이있다. 그러나 A의 필드는 주문이 그들을 사용하는 순서에 배치 될 필요가있다.

  3. ==============================

    3.요약하면,이 작업을 수행하는 세 가지 방법이 있습니다 :

    요약하면,이 작업을 수행하는 세 가지 방법이 있습니다 :

    귀하의 질문에 대답하는 것은 스칼라에 포함 된 모든 표준 기능 목록과 같은 마법을 할 수 있는가 ((2,1), (1,2)). 정렬

    미리 정의 된 순서 부 세트는, 예를 들어,이 문자열, 9 arity에 등까지 튜플.

    이 굴러 쉬운 일이 아니기 때문에 그런 것은 필드 이름이보다는 선험적 (적어도 매크로 마법없이) 할 수 있습니다 방법으로 액세스의 경우 클래스 필드가 다른하지를 알 수없는 점을 감안, 사례 클래스 존재하지 않는다 제품 반복자를 사용하여 / 이름을 지정합니다.

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

    4.컴패니언 객체의 적용된 방법은 튜플 경우 클래스의 첫번째 인수 목록에 대응하는 튜플 옵션 [튜플]로 케이스 클래스 전환을 제공한다. 다시 말해:

    컴패니언 객체의 적용된 방법은 튜플 경우 클래스의 첫번째 인수 목록에 대응하는 튜플 옵션 [튜플]로 케이스 클래스 전환을 제공한다. 다시 말해:

    case class Person(name : String, age : Int, email : String)
    
    def sortPeople(people : List[Person]) = 
        people.sortBy(Person.unapply)
    
  5. ==============================

    5.sortBy 방법 (일종의 태그 필드에) 예를 들어,이 일을 한 전형적인 방법이 될 것입니다 :

    sortBy 방법 (일종의 태그 필드에) 예를 들어,이 일을 한 전형적인 방법이 될 것입니다 :

    scala> l.sortBy(_.tag)foreach(println)
    A(article,2)
    A(lines,7)
    A(words,50)
    
  6. ==============================

    6.당신이 경우 클래스를 사용하기 때문에 당신은 같은 발주로 확장 할 수 :

    당신이 경우 클래스를 사용하기 때문에 당신은 같은 발주로 확장 할 수 :

    case class A(tag:String, load:Int) extends Ordered[A] { 
      def compare( a:A ) = tag.compareTo(a.tag) 
    }
    
    val ls = List( A("words",50), A("article",2), A("lines",7) )
    
    ls.sorted
    
  7. from https://stackoverflow.com/questions/19345030/easy-idiomatic-way-to-define-ordering-for-a-simple-case-class by cc-by-sa and MIT license