2016-09-29 35 views
1

我的人的名单与许多字段的对象,我可以很容易做到:斯卡拉地图功能删除领域

list.map(person => person.getName) 

为了产生与万民的名字另一个集合。

如何使用map函数来创建一个包含Person类的所有字段的新集合,但是他们的名字呢?

换句话说,你如何从一个给定的集合中创建一个新的集合,这个集合将包含你的初始集合的所有元素,并删除它们的一些字段?

+0

你的问题并没有很好的定义。我猜你有一堆“getter”函数,你想要像'list.map(person => Seq(person.getHeight,person.getWeight))''。为了做到这一点,斯卡拉必须知道哪些功能是“吸气”功能。你当然可以通过在你的Person类中保留一个“getter”函数列表并从列表中过滤掉getName,但是这会让你很难维护。另外值得注意的是,Scala风格通常避免getter和setter支持不可变变量。你能描述你为什么要这么做吗? – spiffman

+0

在我的情况下,Person对象实际上是一个拥有许多getter的不可变Java对象 - 我想用一些反射来检索它的所有方法,然后将它们过滤掉,但实际上这太枯燥乏味。我也可以使用map函数来指定我想要映射的getter方法,但是如果你有更多的getter映射而不是排除,那可能也很乏味。我希望scala能提供一些可以在这种情况下使用的单线魔法。 – anton4o

+1

您可以扩展'Person'类以创建字段的“Map”,然后您可以轻松过滤。 '隐式类extendPerson(p:Person){def getAllFields:Map [String,String] = Map(“name” - > p.getName,“age” - > p.getAge,...)'然后是'person。 getAllFields.filterKeys(k => k!=“name”)' – spiffman

回答

4

您可以使用您的case classunapply方法将成员提取为tuple,然后从tuple中删除您不需要的东西。

case class Person(name: String, Age: Int, country: String) 
// defined class Person 

val personList = List(
    Person("person_1", 20, "country_1"), 
    Person("person_2", 30, "country_2") 
) 
// personList: List[Person] = List(Person(person_1,20,country_1), Person(person_2,30,country_2)) 

val tupleList = personList.flatMap(person => Person.unapply(person)) 
// tupleList: List[(String, Int, String)] = List((person_1,20,country_1), (person_2,30,country_2)) 

val wantedTupleList = tupleList.map({ case (name, age, country) => (age, country) }) 
// wantedTupleList: List[(Int, String)] = List((20,country_1), (30,country_2)) 

// the above is more easy to understand but will cause two parses of list 
// better is to do it in one parse only, like following 

val yourList = personList.flatMap(person => { 
    Person.unapply(person) match { 
    case (name, age, country) => (age, country) 
    } 
}) 
// yourList: List[(Int, String)] = List((20,country_1), (30,country_2)) 
+2

单个解析可以简化为:'map {case Person(_,age,country)=>(age,country)}' – jwvh