1

My question is how to iterate objects in Scala even when they are nested within objects?

object Foo {

  case object A extends FirstLevel {
    sealed trait SecondLevel
    case object A1 extends SecondLevel {
      println("you're in A1")
    }
  }

  case object B extends FirstLevel {
    sealed trait SecondLevel
    case object B1 extends SecondLevel {
      sealed trait ThirdLevel
      case object B1B extends ThirdLevel{
        println("now you're in B1B")
      }
    }
  }

}

bar(Foo.FirstLevel) foreach { f =>
  println(f{
  bar(f.SecondLevel foreach { s =>
    println(s)
    bar(s.ThirdLevel) ...
  }
}

// A, A1, B, B1, B1B... // and so on..

I've come close while going through the answer on these questions but they're only good for one level.

1 Answer 1

0

If you hate the code containing the iterated objects' names twice, like:

object Content1 {...}
object Content2 {...}
object Content3 {...}
val iterated = Seq(Content1, Content2, Content3)

then the Macro features have to be used, and I'm not familiar with them :P Also if you need the function to be somehow typed, then please wait for another answer because it should need TypeTags that I don't think I have enough knowledge about.

Otherwise, by that I mean if anything can be the iterated objects, then have all the parents inherit some Traversable, and make a method like:

def iterateAnies(s: Any)(f: Any => Unit) {
  f(s)
  s match {
    case s: Traversable[_] => s.foreach(iterateAnies(_)(f))
    case _ =>
  }
}

If objects need to be HAS-A, then make another trait having a Traversable[_] and modify the iterateAnies method so it takes in the trait as s, have the f takes in the trait too, and the match part is gonna be upside-down:

trait HasTraversable {
  def traversable: Traversable[_]
}

def iterateAnies(s: HasTraversable)(f: HasTraversable => Unit) {
  f(s)
  s.traversable.foreach(_ match {
    case c: HasTraversable => iterateAnies(c)
    case _ => 
  })
}

With this you can print out their toString doing like:

val something: Any = ... //or HasTraversable
iterateAnies(something)(println(_.toString))
iterateAnies(something)(println(_ match {
  case s: String => "text"
  case s: Int    => "number"
  case s: _      => "idk"
)})

To keep track of the depth, add an Int parameter to both iterateAnies and f and increment the value while the process.

If nobody answers and you need it typed like iterateAnies[A], then let me know and I will do my best, but I'm pretty sure somebody's gonna answer even with Macro features :)

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

Comments

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.