0

I'm learning Scala and attempting to filter Map[String, List[Double]] such that within each sliding window of size 2 if the values are less than .1 then the key values map is returned.

For this data:

 val data  : Map[String, List[Double]] = Map(
      "a" -> List(0.086, 0.086, 0.398, -0.312, 0.312, 0.312, 0.312, 0.312, 0.312, 0.312),
      "b" -> List(-0.119, -0.119, 1.007, 1.201, 1.201, 1.201, -1.201, 1.201, 1.201, 1.201))

The Maps: "

"a" -> List(0.086, 0.086)
"b" -> List(-0.119, -0.119)

should be returned as both elements of the List are < .1

I create a sliding window of size 2 :

val sliding = data.map(l => l._2.sliding(2).toList)

sliding contains:

List(List(List(0.086, 0.086), List(0.086, 0.398), List(0.398, -0.312), List(-0.312, 0.312), List(0.312, 0.312), List(0.312, 0.312), List(0.312, 0.312), List(0.312, 0.312), List(0.312, 0.312)), List(List(-0.119, -0.119), List(-0.119, 1.007), List(1.007, 1.201), List(1.201, 1.201), List(1.201, 1.201), List(1.201, -1.201), List(-1.201, 1.201), List(1.201, 1.201), List(1.201, 1.201)))

But using sliding in this way means I've dropped the key's and I'm unsure how to filter this new data structure.

How do filter the values from data? I think I'm over complicating the solution with my use of sliding and that I could using pattern matching instead ?

Update:

Using below code satisfies the condition and produces expected output:

val data  : Map[String, List[Double]] = Map(
  "a" -> List(0.086, -0.398, -0.398, -0.312, 0.312, 0.312, 0.312, 0.312, 0.312, 0.312),
  "b" -> List(-0.119, -0.119, 1.007, 1.201, 1.201, 1.201, -1.201, 1.201, -1.201, -1.201)
)
val result = data.map {
  case (key, value) => key -> value.sliding(2).filter(_.forall(_ < .1)).toList
}.filter {
  case (_, values) => values.nonEmpty
}
println("result "+result)

Which prints:

Map(a -> List(List(0.086, -0.398), List(-0.398, -0.398), List(-0.398, -0.312)), b -> List(List(-0.119, -0.119), List(-1.201, -1.201)))

1 Answer 1

2

If I understood task correctly, then you can go with something like:

val data  : Map[String, List[Double]] = Map(
      "a" -> List(0.086, 0.086, 0.398, -0.312, 0.312, 0.312, 0.312, 0.312, 0.312, 0.312),
      "b" -> List(-0.119, -0.119, 1.007, 1.201, 1.201, 1.201, -1.201, 1.201, 1.201, 1.201),
      "c" -> List(1.201, 1.3)
)

val result = data.map {
  case (key, value) => key -> value.sliding(2).filter(_.forall(_ < 0.1)).toList.flatten
}.filter {
  case (_, values) => values.nonEmpty
}

println(result.mkString("\n"))

Which will print out:

a -> List(0.086, 0.086)
b -> List(-0.119, -0.119)

Scatie: https://scastie.scala-lang.org/nW4ez389T7ysXfVYEVQJUg

Sign up to request clarification or add additional context in comments.

6 Comments

thanks, b -> List(-0.119, -0.119) & a -> List(0.086, 0.086) should be returned as both these values are < .1, your filtering values < 1 not .1 , I've updated question to include the "a" map
@blue-sky Yes, excuse me - I missed that do. Answer updated.
if I change 0.398 to -0.398 (the third element in "a" map) then Map(a -> List(0.086, 0.086, 0.086, -0.398, -0.398, -0.312), b -> List(-0.119, -0.119)) is returned, instead a -> List(0.086, 0.086) b -> List(List(-0.119, -0.119), List(-0.398, -0.312)) should be returned, I should have clarified this but I did not realise until I tested your code..
I just needed to remove flatten it seems, updated Scastie: scastie.scala-lang.org/EFzULvhCRi2lFNyURhwgMg
@blue-sky Sorry, I'm afraid I'm not following you: (0.086, -0.398) - both numbers satisfies condition to be < 0.1 why they should not be present?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.