#scala
#scala
Вопрос:
У меня есть объект Option employee. От employee я хочу получить имя, отдел, адрес, номер, возраст или что-либо еще из него, если оно существует, но если нет, то имя, отдел и все остальное, что я хочу установить в «».
Я хотел бы просто сделать, как в Java:
if (employee.isDefined) {
val name = employee.get.getEmployeName
val department = employee.get.getDepartment
val address = employee.get.getAddress
val number = employee.get.getNumber
val age = employee.get.getAge
} else {
val name, department, address, number, age = ""
}
но я узнал, что это так не работает. Похоже, мне понадобится другой объект employee и установите значения like, а затем получите к нему доступ позже:
if (employee.isDefined) {
emp.setName(employee.get.getEmployeName)
emp.setDepartment(employee.get.getDepartment)
...
} else {
emp.setName("")
emp.setDepartment("")
...
}
Я также экспериментировал с кортежами?
val employeeInfo = employee match {
case Some(emp) => (employee.getEmployeName, employee.getDepartment, employee.getAddress,
employee.getNumber, employee.getAge)
case None => ("", "", "", "", "")
}
val name = employeeInfo._1
val department = employeeInfo._2
val address = employeeInfo._3
...
Подходят ли эти методы? Или есть какие-либо лучшие способы сделать это? Спасибо за помощь
Комментарии:
1. Итак, вы хотите перейти от
Option[Employee]
кEmployee
? Вы можете просто сделатьemployee.getOrElse(Employee("","","",""))
2. Это сработало бы, но я упростил внутри объекта employee есть как бы 50 различных переменных-членов, поэтому мне пришлось бы установить для всех 50 из них пустую строку(«», «», «», «» …). Я просто хочу получить 5-6 переменных или установить их в пустую строку
3. Честно говоря, похоже, что вам нужно переосмыслить свой дизайн. Не очень хорошая идея устанавливать такие значения в пустую строку, не говоря уже о такой сложной структуре данных с 50 полями. Если вы хотите вручную выбрать эти поля, у вас нет другого выбора, кроме как сделать это вручную. Вероятно, вы могли бы определить сложную линзу, чтобы помочь вам, но она не будет короче или чище, чем сопоставление с образцом. Единственное улучшение, которое вы можете сделать здесь, — это свернуть объявления значений до
val (name, department, address, number, age) = employee match {...}
4. Я пытаюсь создать API, в котором, если объект employee существует, он будет отображать правильные значения или просто пустую строку, если нет, возможно, мне следовало быть более ясным. Я мог бы просто вообще опустить эти переменные, если null. Спасибо за ваше предложение, я рассмотрю его
5. Обычной практикой является возврат
404 Not Found
в этом случае. Я никогда не видел, чтобы API возвращал пустой объект, если он не может найти запрошенный ресурс
Ответ №1:
.getOrElse()
это обычный способ извлечения значения из Option
при указании значения по умолчанию, если опция есть None
.
В вашем случае, однако, это контейнер многих значений, которые могут быть None
. Для этого я бы рекомендовал .fold()
.
case class Employee(empName : String
,dept : String
,addr : String
,num : String
,age : String)
val employee: Option[Employee] =
Some(Employee("Jo","mkt","21A","55","44"))
//or None
val name = employee.fold("")(_.empName)
val department = employee.fold("")(_.dept)
val address = employee.fold("")(_.addr)
val number = employee.fold("")(_.num)
val age = employee.fold("")(_.age)
Но я должен согласиться с комментариями от @sinanspd, ваш общий дизайн в лучшем случае сомнителен.
Ответ №2:
Вот как я бы справился с этой конкретной операцией:
val (name, department, address, number, age) =
employee.fold(("", "", "", "", "")) { e =>
(e.getEmployeName, e.getDepartment, e.getAddress, e.getNumber, e.getAge)
}
Но, как было предложено в комментариях, стоит взглянуть на общий дизайн. Например, может быть лучше сохранить значения необязательными:
val employeeData: Option[(String, String, String, String, String)] =
employee.map{ e =>
(e.getEmployeName, e.getDepartment, e.getAddress, e.getNumber, e.getAge)
}
Это позволяет вам определить, является ли значение, ""
потому что employee
было None
или потому, что значение в Employee
объекте было ""
. И вы, вероятно, определили бы другое class
для представления этого ограниченного набора данных сотрудника, чтобы сделать код более чистым и понятнее.