blkpingu
blkpingu

Reputation: 1676

How to remove an element of a sequence A from List[A] that is a value of a map(B->List[A])

I have this data:

//H1 = house name
//H2 = price
//H3 = size
//H4 = location

//List(H1, H2, H3, H4)

val houses = List(
  ("House_A", 250, 120, "NYC"),
  ("House_B", 90, 100, "BR"),
  ("House_C", 300, 500, "BR"),
  ("House_D", 120, 90, "NYC"),
  ("House_E", 320, 250, "BR"),
  ("House_F", 290, 450, "SA"),
  ("House_G", 290, 450, "NYC"),
  ("House_F", 450, 100, "FR"),
  ("House_H", 210, 92, "SA"),
  ("House_I", 240, 100, "FR"),
  ("House_J", 395, 80, "FR"),
  ("House_K", 140, 125, "NYC"),
  ("House_L", 900, 250, "BR"),
  ("House_M", 300, 110, "FR")
)

and want to get to "List places with Houses with price(H1) > 100 and more than 1 house" in this format:

List((H4, List(H1,H2,H3)))

The Problem

My problem is that I can't figure out how to remove H4(place) from the list that is supposed to be List(H1,H2,H3).

What I tried

This is as good as I got it

houses
  .filter(_._2 > 100)
  .groupBy(_._4)
  .filter(a => a._2.length > 1) // this is the map I talk about in the title: Map(H4 -> List(H1, H2, H3, H4))
  .toList
List(
  (BR,List((House_C,300,500,BR), (House_E,320,250,BR), (House_L,900,250,BR))),
  (NYC,List((House_A,250,120,NYC), (House_D,120,90,NYC), (House_G,290,450,NYC), (House_K,140,125,NYC))),
  (FR,List((House_F,450,100,FR), (House_I,240,100,FR), (House_J,395,80,FR), (House_M,300,110,FR))),
  (SA,List((House_F,290,450,SA), (House_H,210,92,SA))))

Upvotes: 0

Views: 80

Answers (1)

You were too close!
You only need to map the inner group so you can remove the unwanted column. And, sicne you need to do that for each inner group, you want to map all the Map.

houses
  .filter(_._2 > 100)
  .groupBy(_._4)
  .filter(a => a._2.length > 1)
  .map {
    case (location, group) =>
      location -> group.map {
        case (house, price, size, _) =>
          (house, price, size)
      }
  }.toList

Bonus: To make the code more efficient you can.

  • Combine filter & map into collect.
  • You do not need all the size of the list, just check if it is greater than 1.
    (this one only applies for Scala 2.13 +)

-

houses
  .filter(_._2 > 100)
  .groupBy(_._4)
  .collect {
    case (location, group) if (group.sizeIs > 1) =>
      location -> group.map {
        case (house, price, size, _) =>
          (house, price, size)
      }
  }.toList

Upvotes: 3

Related Questions