如何将这个具有不可变成员的非功能scala代码转换为优雅的解决方案?
如何避免可变索引并使其更加优雅?我知道必须使用Option更改Null,我只是对答案感到好奇如何将这个具有不可变成员的非功能scala代码转换为优雅的解决方案?,scala,functional-programming,immutability,Scala,Functional Programming,Immutability,如何避免可变索引并使其更加优雅?我知道必须使用Option更改Null,我只是对答案感到好奇 class Person(val name: String, val department: String) var people = Array(new Person(“Jones”, “Marketing”), new Person(“Smith”, “Engineering”)) var engineer: Person = null var index = 0 while (index &l
class Person(val name: String, val department: String)
var people = Array(new Person(“Jones”, “Marketing”), new Person(“Smith”, “Engineering”))
var engineer: Person = null
var index = 0
while (index < people.length) {
if (people(index).department == “Engineering”)
engineer = people(index)
index = index + 1
}
println(engineer.name + “ is an engineer”)
class-Person(val-name:String,val-department:String)
var people=Array(新人(“琼斯”、“营销”)、新人(“史密斯”、“工程”))
变量工程师:Person=null
var指数=0
while(指数<人长){
if(人员(索引)。部门==“工程”)
工程师=人员(索引)
索引=索引+1
}
println(engineer.name+“是工程师”)
以下是我重构的方法:
// Refactored into a case class, since it's a simple data container
case class Person(name: String, department: String)
// Using the case class convenience apply method to drop `new`
val people = Array(Person(“Jones”, “Marketing”), Person(“Smith”, “Engineering”))
// Selects all the engineers. You could add `.headOption` to get the first.
val engineers = people.filter(_.department == "Engineering")
// Functional way of iterating the collection of engineers
// Also, using string interpolation to print
for (engineer <- engineers) println(s"${engineer.name} is an engineer.")
最后一个提示,如果你的部门是固定的选项的有限集合,你也应该考虑把它变成一个类型:
sealed trait Department
case object Engineering extends Department
case object Marketing extends Department
// ... for each valid department
然后你可以根据身份而不是价值来匹配。这使您可以依赖类型系统,而不必经常验证字符串(有些人称为)。最佳做法是尽早将数据验证为类型,将其作为类型化数据处理,然后仅转换回字符串,以便将数据从系统中导出(例如,打印到屏幕、记录、通过API提供服务)。您可以使用
查找
首先查找:
people
.find { _.department == "Engineering" }
.foreach { engineer => println(engineer.name + " is an engineer") }
或过滤器
查找所有:
people
.filter { _.department == "Engineering" }
.foreach { engineer => println(engineer.name + " is an engineer") }
顺便说一下,只需将增量操作移到if
块之外,就可以修复代码:
if (people(index).department == "Engineering") {
engineer = people(index)
// index = index + 1
}
index = index + 1
之后,您应该检查engineer
中的null
,因为您的数组可能不包含符合您的条件的人员
因此,您似乎希望找到最后一个人
,因此您可以使用:
people
.foldLeft(None: Option[Person])((r, p) =>
if (p.department == "Engineering") Some(p) else r)
.foreach { engineer => println(engineer.name + " is an engineer") }
另外,在避免所有var
之后,您还可以将数组
(可变结构)更改为列表
(默认为scala.collection.immutable.List)如果您想找到数组中的最后一个工程师,您可能会使用:
case class Person(val name: String, val department: String)
val people = Array(Person(“Jones”, “Marketing”), Person(“Smith”, “Engineering”))
def findLastEngineer(l: Seq[Person]) : Option[Person] =
people.foldLeft(None) {
case (previousOpt, eng) => if (eng.department == "Engineering") Some(eng) else previousOpt
}
}
println(findLastEngineer(people).map(_.name).getOrElse("Not found"))
我会这样做:
case class Person(name: String, department: String)
val people = List(Person("Jones", "Marketing"), Person("Smith", "Engineering"))
val engineers = people.filter { person:Person => person.department == "Engineering" }
engineers.map { engineer: Person => println(engineer.name + " is an engineer") }
尝试使用函数转换其他类型中的类型。通常我们使用map/reduce/filter函数来实现这一点。此代码包含bug(无限循环)。你想在功能代码中得到这个bug吗?如果你能用文字描述代码片段实际应该做什么,也许会有帮助。所以你想打印列表名称上的最后一个工程师?或者任何?或者首先?这不是一个真正的问题:这是从StackOverflowCareers上的招聘广告中剪下来粘贴的:也许OP应该遵循他们的建议:“如果你必须用谷歌搜索任何东西来做这件事,那么现在可能不是你申请的合适时机。”谁在乎申请呢?谢谢你,这很有启发性和解释性。顺便说一句,工程设计后缺少双引号。对,函数map/reduce/filter已经处理集合中的所有元素,因此我们不必麻烦使用可变索引,只需people.filter(Person.department.equals(“工程”)。last
case class Person(val name: String, val department: String)
val people = Array(Person(“Jones”, “Marketing”), Person(“Smith”, “Engineering”))
def findLastEngineer(l: Seq[Person]) : Option[Person] =
people.foldLeft(None) {
case (previousOpt, eng) => if (eng.department == "Engineering") Some(eng) else previousOpt
}
}
println(findLastEngineer(people).map(_.name).getOrElse("Not found"))
case class Person(name: String, department: String)
val people = List(Person("Jones", "Marketing"), Person("Smith", "Engineering"))
val engineers = people.filter { person:Person => person.department == "Engineering" }
engineers.map { engineer: Person => println(engineer.name + " is an engineer") }