Как я могу сортировать объекты List[Int]?

Что я хочу сделать, так это сортировать объекты List в Scala, а не сортировать элементы в списке. Например, если у меня есть два списка целых чисел:

val l1 = List(1, 2, 3, 7)
val l2 = List(1, 2, 3, 4, 10)

Я хочу иметь возможность расставить их по порядку, где l1 > l2.

Я создал класс case, который делает то, что мне нужно, но проблема в том, что когда я его использую, ни один из моих других методов не работает. Нужно ли мне реализовывать все остальные методы в классе, например, flatten, sortWith и т. д.?

Код моего класса выглядит так:

class ItemSet(itemSet: List[Int]) extends Ordered[ItemSet] {

  val iSet: List[Int] = itemSet

  def compare(that: ItemSet) = {

    val thisSize = this.iSet.size
    val thatSize = that.iSet.size
    val hint = List(thisSize, thatSize).min
    var result = 0
    var loop = 0

    val ths = this.iSet.toArray
    val tht = that.iSet.toArray

    while (loop < hint && result == 0) {
      result = ths(loop).compare(tht(loop))
      loop += 1
    }
    if (loop == hint && result == 0 && thisSize != thatSize) {
      thisSize.compare(thatSize)
    } else
      result
  }

}

Теперь, если я создам массив наборов элементов, я могу его отсортировать:

val is1 = new ItemSet(List(1, 2, 5, 8))
val is2 = new ItemSet(List(1, 2, 5, 6))
val is3 = new ItemSet(List(1, 2, 3, 7, 10))

Array(is1, is2, is3).sorted.foreach(i => println(i.iSet))

scala> List(1, 2, 3, 7, 10)
List(1, 2, 5, 6)
List(1, 2, 5, 8)

Два метода, которые доставляют мне проблемы:

def itemFrequencies(transDB: Array[ItemSet]): Map[Int, Int] = transDB.flatten.groupBy(x => x).mapValues(_.size)

Ошибка, которую я получаю:

Выражение типа Map[Nothing, Int] не соответствует ожидаемому типу Map[Int, Int]

И для этого:

def sortListAscFreq(transDB: Array[ItemSet], itemFreq: Map[Int, Int]): Array[List[Int]] = {
  for (l <- transDB) yield
    l.sortWith(itemFreq(_) < itemFreq(_))
}

Я получил:

Не удается разрешить символ sortWith.

Есть ли способ просто расширить список [Int], чтобы я мог сортировать набор списков, не теряя функциональности других методов?


person Mike Lavender    schedule 05.07.2013    source источник


Ответы (1)


Стандартная библиотека предоставляет лексикографический порядок для коллекции заказанных вещей. Вы можете поместить его в область действия, и все готово:

scala> import scala.math.Ordering.Implicits._
import scala.math.Ordering.Implicits._

scala> val is1 = List(1, 2, 5, 8)
is1: List[Int] = List(1, 2, 5, 8)

scala> val is2 = List(1, 2, 5, 6)
is2: List[Int] = List(1, 2, 5, 6)

scala> val is3 = List(1, 2, 3, 7, 10)
is3: List[Int] = List(1, 2, 3, 7, 10)

scala> Array(is1, is2, is3).sorted foreach println
List(1, 2, 3, 7, 10)
List(1, 2, 5, 6)
List(1, 2, 5, 8)

Класс типа Ordering часто более удобен, чем Ordered в Scala — он позволяет указать порядок упорядочения некоторых существующих типов без изменения его кода или создания прокси-класса, расширяющего Ordered[Whatever], который, как вы видели, может очень быстро запутаться.

person Travis Brown    schedule 05.07.2013
comment
Большое спасибо! Я не могу поверить, что потратил 2 дня, пытаясь заставить все работать. - person Mike Lavender; 05.07.2013
comment
@Val, я думаю, это сарказм, но вы как бы упускаете суть — массив списков не сортируется перед вызовом .sorted, а затем сортируется. Кроме того, я просто использую примеры ОП, что, как правило, является хорошей идеей. - person Travis Brown; 25.06.2014