2016-09-29 2 views
1

У меня есть список объектов Person со многими полями, и я могу легко сделать:Scala карта функция для удаления полей

list.map(person => person.getName) 

Для того, чтобы сформировать другую коллекцию всех имен народов.

Как вы можете использовать функцию карты для создания новой коллекции со всеми полями класса Person, НО их имя?

Другими словами, как вы можете создать новую коллекцию из данной коллекции, которая будет содержать все элементы вашей первоначальной коллекции с удалением некоторых из их полей?

+0

Ваш вопрос на самом деле не определен. Я предполагаю, что у вас есть куча функций «getter», и вы хотите что-то вроде 'list.map (person => Seq (person.getHeight, person.getWeight))'. Для этого Scala должен был знать, какие функции являются функциями «getter». Вы, конечно, могли бы это сделать, сохранив список функций «getter» в вашем классе «Person» и отфильтровывая «getName» из этого списка, но это утомительно для поддержания. Также стоит отметить, что стиль Scala обычно избегает геттеров и сеттеров в пользу неизменных переменных. Можете ли вы описать, почему вы хотите это сделать? – spiffman

+0

В моем случае объект Person фактически является неизменным объектом Java с множеством геттеров - я думал об использовании некоторого отражения, чтобы извлечь все его методы, а затем отфильтровать их, но это слишком утомительно. Я также могу использовать функцию карты, чтобы указать, какие методы getter я бы хотел отобразить, но в случае, если у вас больше карт-источников, чем для исключения, это тоже может утомиться. Я надеялся, что scala может предоставить некоторую однострочную магию, которая может быть использована в таких случаях. – anton4o

+1

Вы можете расширить класс 'Person', чтобы создать поля« Карта », которые затем можно легко фильтровать. 'implicit class extendPerson (p: Person) {def getAllFields: Map [String, String] = Map (" name "-> p.getName," age "-> p.getAge, ...)', а затем 'person. getAllFields.filterKeys (k => k! = "name") ' – spiffman

ответ

4

Вы можете использовать unapply метод вашего case class для извлечения членов в 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

Смежные вопросы