Avi Kaminetzky
Avi Kaminetzky

Reputation: 1538

Scala For Comprehension with Filter

I am using Scala's for comprehension to produce a modified facetFilter. If a value in facetFilter doesn't exist in allFacets, it should be filtered out. Currently, the newFacetFilter doesn't filter at all.

val allFacets = Map(
  "band_material" -> Map("Rubber" -> 11),
  "dial_color" -> Map("Ivory" -> 68, "Salmon"-> 3))


val facetFilter =
  Map("band_material" -> List("Yellow Gold Plated", "Rubber"),
    "dial_color" -> List("Ivory"))

val newFacetFilter =
  for {
    (k,v) <- allFacets
    (facetName, facetArr) <- facetFilter
    aFacet <- facetArr
    if k != facetName || !v.contains(aFacet)
  } yield (facetName -> facetArr)

Current Output of newFacetFilter:

Map("band_material" -> List("Yellow Gold Plated", "Rubber"), "dial_color" -> List("Ivory"))

Expected Output of newFacetFilter:

Map("band_material" -> List("Rubber"), "dial_color" -> List("Ivory"))

See this fiddle

Upvotes: 0

Views: 3071

Answers (2)

Andrey Tyukin
Andrey Tyukin

Reputation: 44957

Try this:

val newFacetFilter = 
  for ((k,vs) <- facetFilter) 
  yield (k, vs filter allFacets(k).contains)

Output:

Map(band_material -> List(Rubber), dial_color -> List(Ivory))

Upvotes: 4

retrospectacus
retrospectacus

Reputation: 2586

OK, if we are done with edits, I think this is what you want...

val allFacets = Map(
  "band_material" -> Map(
    "Rubber" -> 11
  ),
  "dial_color" -> Map(
    "Ivory" -> 68,
    "Salmon"-> 3
  )
)

val facetFilter = Map(
  "band_material" -> List("Yellow Gold Plated", "Rubber"),
  "dial_color" -> List("Ivory"),
  "case_material" -> List(),
  "movement" -> List(),
  "price_range" -> List(),
  "gender" -> List()
)

val newFacetFilter = for {
  (facetName, facetArr) <- facetFilter
  (k,v) <- allFacets
  if k == facetName
} yield (facetName, facetArr intersect v.keys.toList)

We simply iterate both maps and when we have the same keys, we intersect the two lists.

Edit: There is a more efficient way, using the Map's get function instead of just iterating everything and ignoring non-matches.

val newFacetFilter = facetFilter.flatMap {
  case (n, fs) => 
    allFacets.get(n).map(n -> _.keys.toList.intersect(fs))
}

So we take each facetFilter entry ((n, fs)), check allFacets for n, then intersect the optional result with our list fs. If n did not exist, we propagate None and it is flattened out by flatMap.

Upvotes: 1

Related Questions