Cách tốt nhất để làm một loại nghịch đảo trong scala là gì? Tôi tưởng tượng sau đây là hơi chậm.
list.sortBy(_.size).reverse
Có một cách sử dụng sortBy thuận tiện nhưng nhận được một loại ngược lại? Tôi thà không cần sử dụng sortWith
.
Cách tốt nhất để làm một loại nghịch đảo trong scala là gì? Tôi tưởng tượng sau đây là hơi chậm.
list.sortBy(_.size).reverse
Có một cách sử dụng sortBy thuận tiện nhưng nhận được một loại ngược lại? Tôi thà không cần sử dụng sortWith
.
Câu trả lời:
Có thể có cách rõ ràng để thay đổi dấu hiệu, nếu bạn sắp xếp theo một số giá trị số
list.sortBy(- _.size)
Tổng quát hơn, việc sắp xếp có thể được thực hiện bằng phương pháp được sắp xếp với một Thứ tự ngầm, mà bạn có thể làm rõ ràng và Đặt hàng có một đảo ngược (không phải là danh sách đảo ngược bên dưới) Bạn có thể làm
list.sorted(theOrdering.reverse)
Nếu thứ tự bạn muốn đảo ngược là thứ tự ngầm, bạn có thể nhận được nó bằng cách ngầm định [Đặt hàng [A]] (Loại bạn đang đặt hàng) hoặc Đặt hàng tốt hơn [A]. Đó sẽ là
list.sorted(Ordering[TheType].reverse)
sortBy giống như sử dụng Ordering.by, vì vậy bạn có thể làm
list.sorted(Ordering.by(_.size).reverse)
Có thể không phải là ngắn nhất để viết (so với trừ) nhưng ý định là rõ ràng
Cập nhật
Dòng cuối cùng không hoạt động. Để chấp nhận _
in Ordering.by(_.size)
, trình biên dịch cần biết chúng ta đang sắp xếp loại nào, để nó có thể gõ _
. Có vẻ như đó sẽ là loại phần tử của danh sách, nhưng điều này không phải như vậy, vì chữ ký được sắp xếp là
def sorted[B >: A](ordering: Ordering[B])
. Thứ tự có thể được bật A
, nhưng cũng có thể trên bất kỳ tổ tiên nào A
(bạn có thể sử dụng byHashCode : Ordering[Any] = Ordering.by(_.hashCode)
). Và thực sự, thực tế danh sách đó là covariant buộc chữ ký này. Một người có thể làm
list.sorted(Ordering.by((_: TheType).size).reverse)
nhưng điều này là ít dễ chịu hơn nhiều.
list.sortBy(x => (-x.size, x.forTiesUseThisField))
list.sorted(Ordering.by((_: TheType).size).reverse)
xem xét list.sorted(Ordering.by[TheType, Int](_.size).reverse)
nó rõ ràng hơn (nhưng lâu hơn) cho quan điểm của tôi về veiw.
list.sortBy(_.size)(Ordering[Int].reverse)
cũng thích .
có lẽ để rút ngắn nó thêm một chút:
def Desc[T : Ordering] = implicitly[Ordering[T]].reverse
List("1","22","4444","333").sortBy( _.size )(Desc)
Dễ dàng dễ dàng (ít nhất là trong trường hợp 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)
sortBy
có tham số ngầm ord
cung cấp thứ tự
def sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A]
vì vậy, chúng ta có thể định nghĩa Ordering
đối tượng riêng
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)
Cả hai sortWith
và sortBy
có một cú pháp nhỏ gọn:
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))
Tôi tìm thấy một trong những sortWith
dễ hiểu hơn.
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)
Một khả năng khác trong trường hợp bạn truyền một hàm mà bạn không thể sửa đổi trực tiếp thành Arraybuffer thông qua sortWith chẳng hạn:
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
đây là mã của tôi;)
val wordCounts = logData.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey((a, b) => a + b)
wordCounts.sortBy(- _._2).collect()