2016-08-08 5 views
1

ich die folgenden Typen haben:Transformation eine Liste auf eine Karte

case class Category(id: Int, name: String) 
case class Product(id: Int, location: Location, categoryIdList: Option[List[Int]]) 

eine Liste der Produkte gegeben

val products:List[Product] = loadProducts() 

Wie kann ich Produkt eine Karte von categoryId zu Ort?

Map[categoryId, Location] 

So würde meine Methode wie folgt aussehen:

def getMap(products: List[Product]): Map[Int, Location] = { 
    ?? 
} 

Ich muss irgendwie über die optionale Liste von categoryIdList laufen und dann eine Karte aus, dass mit der Location-Eigenschaft erstellen.

+2

Was passiert, wenn zwei Produkte mit den gleichen categoryId aber unterschiedliche Orte? Ihre erklärte Karte würde Informationen über einen von ihnen verlieren. – Daenyth

+0

@Daenyth einfach ignorieren, für jetzt, in meinem Fall wird es nicht passieren –

+0

Auch, Option [List [Int]] 'ist nicht ein sehr nützlicher Typ - semantisch Sie sagen" Produkt kann oder nicht haben eine Liste von categoryIds, die leer sein können oder nicht ". Besser wäre 'Option [NonEmptyList]' anstatt, oder wenn Sie effizienter getMap wollen, dann wäre 'Set [Int] 'besser – Daenyth

Antwort

3

Um Seq zu einem Map wir es ein Seq[(Int,Location)], das ist ein Seq ein Tuple2 zu sein, zuerst konvertieren müssen zu konvertieren. Nur dann ist die toMap Methode tatsächlich verfügbar.

Bearbeiten: Okay, hier ist eine Implementierung basierend auf jeder categoryId auf der Liste, beachten Sie, dass Sie eine Option einer Liste nicht verwenden sollten, da ein leerer Zustand für eine Liste nur eine leere Liste ist.

def getMap(products: List[Product]): Map[Int, Location] = { 
    products.flatMap(toListTuple2).toMap 
} 

def toListTuple2(product: Product): List[(Int, Location)] = { 
    product.categoryIdList 
    .getOrElse(List()) 
    .map(category => (category, product.location)) 
} 

So, hier wir zuerst unser Produkt in eine Liste von categoryId s drehen und Locations und dann flatmap es zu einem List von (Int, Location), die dann in eine Map gedreht werden kann durch toMap aufrufen.

+0

Die Produktklasse hat eine Liste von categoryId, es ist in der Fallklasse. –

+0

Ja, aber welche in der Liste willst du? Eine 'Map [Int, Location]' hat nur einen, nein? –

+0

für jedes Produkt muss es alle Kategorien durchlaufen und eine Karte zwischen jeder Kategorie-ID und dem Standort für das Produkt erstellen. –

2

Dies sollte das tun, was Sie fordern jedoch Lösung keine Probleme in den Kommentaren versehen Adresse:

def getMap(products: List[Product]): Map[Int, Location] = { 
    val locations = scala.collection.mutable.Map[Int, Location]() 
    for { 
    product <- products 
    if product.categoryIdList.nonEmpty 
    category <- product.categoryIdList.get 
    } { 
    locations(category) = product.location 
    } 
    locations.toMap 
} 
0
def getMap(products: List[Product]) = { 
     products.map(p => (p.categoryIdList.getOrElse(List.empty), p.location)) 
       .flatMap(x => x._1.map(_ -> x._2)) 
       .toMap 
} 
Verwandte Themen