Статьи

Scala Карты и сортировка

Это запись в блоге, изначально написанная в середине мая 2014 года. Кажется, я также пишу этот код каждые 3 месяца или около того, а потом забыла. Поэтому мне нужен триггер, чтобы точно запомнить, как работает Scala Maps, и сортировать записи по ключу.
Давайте разберемся с Scala REPL.

1
2
3
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.

Мы создадим карту коллекции String, связанной с элементами Integer. Эти данные могли бы стать хранилищем ключевых значений, или у вас может быть аналогичное требование для работы со статистическими данными.

1
2
scala> val map = Map( "Jane" -> 3, "Peter" -> 10, "Steve" -> 1, "Anna" -> 5, "Megan" -> 15, "Brian" -> 7, "Sally" ->  8 )
map: scala.collection.immutable.Map[String,Int] = Map(Megan -> 15, Anna -> 5, Jane -> 3, Brian -> 7, Steve -> 1, Sally -> 8, Peter -> 10)

Чтобы отсортировать структуру данных, мы затем преобразовываем карту в список наборов кортежей.

1
2
scala> map.toList
res1: List[(String, Int)] = List((Megan,15), (Anna,5), (Jane,3), (Brian,7), (Steve,1), (Sally,8), (Peter,10))

Теперь мы можем сортировать, используя кортежи. Вот порядок убывания значений:

1
2
scala> map.toList.sortWith( (x,y) => x._2 > y._2 )
res2: List[(String, Int)] = List((Megan,15), (Peter,10), (Sally,8), (Brian,7), (Anna,5), (Jane,3), (Steve,1))

Здесь порядок возрастания значений

1
2
scala> map.toList.sortWith( (x,y) => x._2 < y._2 )
res3: List[(String, Int)] = List((Steve,1), (Jane,3), (Anna,5), (Brian,7), (Sally,8), (Peter,10), (Megan,15))

Вот еще один совет. Допустим, вам нужно создать гистограмму из 100 различных товаров. Вы можете создать эту структуру данных
неизменным в начале. Однако, поскольку вы строите статистику, вы можете вместо этого использовать изменяемую карту коллекции.

1
2
val buckets = collection.mutable.Map.empty[Int,Int]
    buckets ++= (1 to 100).toList.map{ x => (x,0) }.toMap

Теперь в вашей части сбора статистики вы можете написать что-то вроде этого:

1
2
3
val keyName: String = ???
    val keyIndex: Integer = convertNameToIndex(keyName)
    buckets(keyIndex) =  buckets.getOrElse(keyIndex, 0) + 1

А затем визуализировать отсортированные данные в десятку лучших продуктов

1
2
val sortedProducts = buckets.toList.sortWith{ (x,y) => x._2 > y._2 }
 println(sortedProducts.take(10))

Это все.