wayneeusa
wayneeusa

Reputation: 194

Scala: Assign names to anonymous objects in List

I'd like to know how to name objects in a list by a field

case class age(id: Int,name:String,age:Int)
val people: List[age] = List(age(2,"Angela",31),age(3,"Rick",28))

In this minimum example, I'd like to create objects Angela and Rick.

My initial idea:

val objects: List[age] = people.map( x => {val x.name = new age(x.name,x.age) })

But of course val x.name doesn't work because u can't use a variable name in a variable name.

This isn't an actual problem on a project but rather a concept I am stuck on.

Upvotes: 0

Views: 272

Answers (2)

ljleb
ljleb

Reputation: 312

A simple solution is to use a map:

case class Person(id: Int, name: String, age: Int)
val people: List[Person] = List(Person(2, "Angela", 31), Person(3, "Rick", 28))

val peopleByName: Map[String, Person] = people // List[Person]
  .map(p => (p.name, p))                       // List[(String, Person)]
  .toMap                                       // Map[String, Person]

or, starting with a Map instead of a List:

case class Person(id: Int, age: Int)

val peopleByName: Map[String, Person] = Map(
  "Angela" -> Person(2, 31), // (String, Person)
  "Rick" -> Person(3, 28)    // (String, Person)
)                            // Map[String, Person]

However, if you want to define a member at runtime, then you'll have to extend the Dynamic trait (code snippet from here, the import is mine (required, otherwise the compiler won't be happy)):

import scala.language.dynamics

class DynImpl extends Dynamic {
  def selectDynamic(name: String) = name
}

scala> val d = new DynImpl
d: DynImpl = DynImpl@6040af64

scala> d.foo
res37: String = foo

scala> d.bar
res38: String = bar

scala> d.selectDynamic("foo")
res54: String = foo

If you really want to do this, then I suggest this implementation:

class DynamicPeople(peopleByName: Map[String, Person]) extends Dynamic {
  def selectDynamic(name: String) = peopleByName(name)
}

Upvotes: 1

Yaroslav Fyodorov
Yaroslav Fyodorov

Reputation: 739

It's not clear what's your intent. Do you want to create variables named angela and rick? You can do it manually for small number of list element and for large number of list element this doesn't make sense, because how would you use your 100 variables? It seems you are talking about some mapping from names to properties and then Map will probably suit you the best

val peopleMap: Map[String,age] = people.map(p => p.name -> p). // this will create list of pairs
                toMap //  this will turn it to a Map

pritnln(peopleMap("Angela")) // now you can use person name to get all the info about them

Upvotes: 1

Related Questions