Транспонирование произвольного набора наборов в Scala

Мне часто приходится транспонировать «прямоугольную» коллекцию-коллекций в Scala, например: список карт, карту списков, карту карт, набор списков, карту наборов и т. д. Поскольку коллекции можно единообразно рассматривать как сопоставление определенного домена с содоменом (например, List[A]/Array[A] — это сопоставление домена Int с содоменом A, Set[A] — это сопоставление домена A с логическим содоменом и т. д.), я хотел бы написать чистую общую функцию для выполнения операции транспонирования (например, превратить карту списков в транспонированный список карт). Однако у меня возникли проблемы, потому что, кроме оператора (), у Scala, похоже, нет унифицированного API для абстрактного просмотра коллекций как сопоставлений?

В итоге я написал отдельный транспонированный метод для каждого типа коллекций-коллекций следующим образом:

def transposeMapOfLists[A,B]( mapOfLists: Map[A,List[B]] ) : List[Map[A,B]] = {
  val k = ( mapOfLists keys ) toList
  val l = ( k map { mapOfLists(_) } ) transpose;
  l map {  v => ( k zip v ) toMap }
}

def transposeListOfMaps[A,B]( listOfMaps: List[Map[A,B]]) : Map[A,List[B]] = {
  val k = ( listOfMaps(0) keys ) toList
  val l = ( listOfMaps map { m => k map { m(_) } } ) transpose;
  ( k zip l ) toMap
}

def transposeMapOfMaps[A,B,C]( mapOfMaps: Map[A,Map[B,C]] ) : Map[B,Map[A,C]] = {
  val k = ( mapOfMaps keys ) toList
  val listOfMaps = k map { mapOfMaps(_) }
  val mapOfLists = transposeListOfMaps( listOfMaps )
  mapOfLists map { p => ( p._1, ( k zip p._2 ) toMap ) }
}

Может ли кто-нибудь помочь мне объединить эти методы в одну общую транспонированную коллекцию-коллекций? Это также поможет мне (и я уверен, что другим) изучить некоторые полезные функции Scala в процессе.

ps: я проигнорировал обработку исключений и предположил, что входная коллекция коллекций имеет прямоугольную форму, т. е. все элементы предметной области внутренних коллекций составляют один и тот же набор.

9
задан Ashwin 19 May 2012 в 05:04
поделиться