2013-07-05 2 views
7

Что я хочу сделать, так это сортировать объекты списка в scala, а не сортировать элементы в списке. Например, если у меня есть два списка Ints:Как я могу отсортировать объекты List [Int] в scala?

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

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

Я создал класс case, который делает то, что мне нужно, но проблема в том, что когда я его использую, ни один из моих других методов не работает. Нужно ли мне реализовать все другие методы в классе, то есть сгладить, 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) 

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

Выражение типа карты [Ничего, Int] не соответствует ожидаемому типу карты [Int, Int]

и для этого один:

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

я получаю:

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

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

ответ

14

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

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 type class часто более удобно, чем Ordered в Scala-он позволяет определить, как должны быть упорядочены некоторые существующие типа без необходимости изменять свой код или создать прокси-класс, который расширяет Ordered[Whatever], который, как вы видели, может стать очень грязным.

+0

спасибо! Я не могу поверить, что просто потратил 2 дня, пытаясь заставить все работать. –

+0

@Val, я предполагаю, что это сарказм, но вы как бы упускаете точку - _array_ списков _not_ сортируется перед вызовом '.sorted', а затем это так. Также я просто использую примеры OP, что, как правило, хорошая идея. –

Смежные вопросы