스칼라에서 역 정렬하는 가장 좋은 방법은 무엇입니까?


137

스칼라에서 역 정렬을 수행하는 가장 좋은 방법은 무엇입니까? 다음이 다소 느리다고 생각합니다.

list.sortBy(_.size).reverse

sortBy를 사용하지만 반대 정렬을 얻는 편리한 방법이 있습니까? 오히려 사용할 필요가 없습니다 sortWith.


1
아래의 솔루션은 모두 훌륭하지만 여전히이 독해를 독창적으로 수행하는 원래 방법을 찾습니다. 나는 당신이 생각 한대로이 쓰기 방법에 계산상의 단점이 있음을 확인했습니다. 내가 한 테스트는 다음과 같습니다 .val clock = new Timer (1 to 1e6.toInt) .sorted (Ordering [Int] .reverse) clock.addLap ( "correct way") (1 to 1e6.toInt) .sorted.reverse clock.addLap ( "올바르지 않은 방법") println (clock.toString) [올바른 방법, 랩 = 76, dur. = 76] | [잘못된 방법, 랩 = 326, dur. = 250]
Khoa

답변:


242

숫자 값으로 정렬하면 부호를 변경하는 확실한 방법이있을 수 있습니다.

list.sortBy(- _.size)

더 일반적으로, 정렬은 암시 적 순서로 정렬 된 방법으로 수행 될 수 있으며, 명시 적으로 만들 수 있으며 순서는 반대입니다 (아래의 목록이 아님).

list.sorted(theOrdering.reverse)

역순으로 정렬하려는 순서가 암시 적 순서 인 경우, 암시 적으로 [주문 [A]] (주문하려는 유형) 또는 더 나은 순서 [A]로 주문할 수 있습니다. 그건

list.sorted(Ordering[TheType].reverse)

sortBy는 Ordering.by를 사용하는 것과 같습니다.

list.sorted(Ordering.by(_.size).reverse)

아마도 가장 짧은 글은 아니지만 (마이너스에 비해) 의도는 분명 할 것입니다

최신 정보

마지막 줄이 작동하지 않습니다. _in 을 수락하려면 Ordering.by(_.size)컴파일러에서 어떤 유형을 주문하는지 알아야하므로을 입력 할 수 있습니다 _. 목록의 요소 유형이 될 수도 있지만 sorted의 서명이 그렇기 때문에 그렇지 않습니다 def sorted[B >: A](ordering: Ordering[B]). 의 주문은에있을 수 A있지만의 조상에 A있을 수도 있습니다 (사용 가능 byHashCode : Ordering[Any] = Ordering.by(_.hashCode)). 실제로,리스트가 공변량이라는 사실은이 서명을 강요합니다. 하나는 할 수 있습니다

list.sorted(Ordering.by((_: TheType).size).reverse)

그러나 이것은 훨씬 덜 유쾌합니다.


매우 도움이되었습니다-멍청한 질문을하고 있는지 잘 모르겠지만, 나는 당신의 대답에서 많은 것을 배웠습니다!
schmmd

작동하지 않는 것을 제외하고. REPL 핸디가 없을 때는 절대 대답하지 않아야합니다. 업데이트를 참조하십시오.
Didier Dupont

보조 필드를 정렬하려면 튜플을 반환하십시오.list.sortBy(x => (-x.size, x.forTiesUseThisField))
Brent Faust

2
대신 list.sorted(Ordering.by((_: TheType).size).reverse)고려 list.sorted(Ordering.by[TheType, Int](_.size).reverse)가 명확하게 (그러나 더 이상) veiw의 내 포인트.
Cherry

5
나도 개인적으로 좋아한다 list.sortBy(_.size)(Ordering[Int].reverse).
dtech


27

어쩌면 조금 더 단축시킬 수도 있습니다.

def Desc[T : Ordering] = implicitly[Ordering[T]].reverse

List("1","22","4444","333").sortBy( _.size )(Desc)

19

쉬운 peasy (최소한의 경우 size) :

scala> val list = List("abc","a","abcde")
list: List[java.lang.String] = List(abc, a, abcde)

scala> list.sortBy(-_.size)
res0: List[java.lang.String] = List(abcde, abc, a)

scala> list.sortBy(_.size)
res1: List[java.lang.String] = List(a, abc, abcde)

9

sortByord순서를 제공하는 암시 적 매개 변수 가 있음

def sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A]

그래서 우리는 자신의 Ordering객체를 정의 할 수 있습니다

scala> implicit object Comp extends Ordering[Int] {
 | override def compare (x: Int, y: Int): Int = y - x
 | }
defined module Comp

List(3,2,5,1,6).sortBy(x => x)
res5: List[Int] = List(6, 5, 3, 2, 1)

9

모두 sortWith와 것은 sortBy소형 구문이 :

case class Foo(time:Long, str:String)

val l = List(Foo(1, "hi"), Foo(2, "a"), Foo(3, "X"))

l.sortWith(_.time > _.time)  // List(Foo(3,X), Foo(2,a), Foo(1,hi))

l.sortBy(- _.time)           // List(Foo(3,X), Foo(2,a), Foo(1,hi))

l.sortBy(_.time)             // List(Foo(1,hi), Foo(2,a), Foo(3,X))

sortWith이해하기 쉬운 것을 찾았습니다 .


8
val list = List(2, 5, 3, 1)
list.sortWith(_>_) -> res14: List[Int] = List(5, 3, 2, 1)
list.sortWith(_<_) -> res14: List[Int] = List(1, 2, 3, 5)

질문을 다루지 않습니다.
물결표

1

sortWith를 통해 Arraybuffer로 직접 수정하지 못할 수있는 함수를 전달하는 경우의 또 다른 가능성은 다음과 같습니다.

val buf = collection.mutable.ArrayBuffer[Int]()
buf += 3
buf += 9
buf += 1

// the sort function (may be passed through from elsewhere)
def sortFn = (A:Int, B:Int) => { A < B }

// the two ways to sort below
buf.sortWith(sortFn)                        // 1, 3, 9
buf.sortWith((A,B) => { ! sortFn(A,B) })    // 9, 3, 1

0

이것은 내 코드입니다.)

val wordCounts = logData.flatMap(line => line.split(" "))
                        .map(word => (word, 1))
                        .reduceByKey((a, b) => a + b)

wordCounts.sortBy(- _._2).collect()

1
이것은 정확하지 않지만 흥미로운 부분 (두 번째 줄)은 그 전에 불필요한 줄로 익사합니다. 기본적으로 역순 정렬을 수행하는 한 가지 방법은 정렬 값을 무효화하는 것입니다.
Carl-Eric Menzel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.