【问题标题】:Scala list append a class in list and retrieve itemScala列表在列表中附加一个类并检索项目
【发布时间】:2015-02-17 14:31:42
【问题描述】:

scala 的新手,所以缺少列表的基本内容。

我正在尝试列出以下课程的列表

  case class Person (val name: String, val age:Int, val email: String)

如何创建一个不可变的 Person 类列表?

我试过了:-

val list: List[Person] = List(Person("",0,"")) // compilation ok
list.::(person) // compile ok

但是当我检查大小时,它是 1。它应该是 2。而且我没有在列表中看到添加的人。

请让我知道如何制作 Person 类列表,插入新人,然后根据年龄、姓名、电子邮件或索引检索人。

请不要让我参考 api doc http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List

很难理解 :(

【问题讨论】:

    标签: list scala


    【解决方案1】:

    试试这个。

       val list2 = list.::(person)
    

    记住list 是不可变的。 list2 的大小应该是 2。

    【讨论】:

      【解决方案2】:

      记住前面提到的不可变列表,对于

      case class Person (val name: String = "", 
                         val age:Int = 0, 
                         val email: String = "")
      

      (请注意,您可以为每个字段设置构造默认值)和

      val list: List[Person] = List(Person("",0,"")) // compilation ok
      

      我们也可以使用List 连接运算符++ 构造第二个List[Person],如下所示,

      val list2 = list ++ List(Person(age=1)) 
      list2: List(Person(,0,), Person(,1,))
      

      要通过给定标准检索Person,例如在本例中,通过age,请考虑collect,如下所示,

      val list3 = list2.collect { case p@Person(_, age, _) if age == 1 => p }
      List[Person] = List(Person(,1,))
      

      这里我们提取感兴趣的字段age,并检查一个条件(是否等于1),因此我们选择list2中的那些符合条件的条目;为了提供此类条目,我们在每个 Person 实例上使用绑定 p;也许更规范(并且不必要地重复)的方法是

      val list3 = list2.collect { 
        case Person(name, age, email) if age == 1 => Person(name, age, email) }
      

      类似的方法依赖于filter,如下所示,

      list2.filter(p => p.age == 1)
      

      还有一个 for 理解,像这样

      for ( p@Person(n, a, e) <- list2  if a == 1 ) yield p
      

      在条目列表上定义选择的更详细的方法包括定义将谓词作为参数并针对每个条目对其进行评估的方法;此外,这可以封装在一个隐式类中以便于使用;因此考虑这个例子,

      implicit class PersonsOps( val persons: List[Person] ) extends AnyVal {
        def select(pred: Person => Boolean) = persons.filter(pred)
      }
      

      所以我们可以在byAge的调用中定义一个匿名函数,即(x: Person) =&gt; x.age == 1;因此

      list2.select( (x: Person) => x.age == 1 )
      

      或等效

      list2.select( _.age == 1 )
      

      请注意,在此说明性示例中,selectfilter 是等效的或可互换的,但 select 可以根据其他要求进行丰富/扩展。

      【讨论】:

        【解决方案3】:

        正如 Soumya Simanta 所说,您有一个不可变的列表,因此您必须将 :: 运算符返回的 List 分配给新的 val。顺便说一句,您可以使用以下符号

        val list2 = person :: list
        

        相当于

        val list2 = list.::(person)
        

        要获取您的Person 实例的信息,您可以使用以下行:

        list2 foreach { p: Person => println(p.email) }
        

        foreachList 的一个方法。它将一个函数(例如{ p: Person =&gt; println(p.email) })应用于列表的所有元素。

        【讨论】:

          【解决方案4】:
          list.::(person)
          

          检索一个新列表,包含两个元素:旧的和新的。但是,该操作不会更改您的列表,称为列表。试试这个方法:

          var list: List[Person] = List(Person("",0,"")) // compilation ok
          list = list.::(person) // compile ok
          

          【讨论】:

          • 那不会编译,因为你不能重新分配valvar 会起作用,尽管它的风格仍然很糟糕。
          猜你喜欢
          • 2021-03-17
          • 1970-01-01
          • 1970-01-01
          • 2020-01-18
          • 1970-01-01
          • 2020-08-21
          • 1970-01-01
          • 1970-01-01
          • 2017-04-14
          相关资源
          最近更新 更多