我正在学习Scala,因为它很符合我的需求,但我发现很难优雅地构造代码.我处于一种情况,我有一个List x并且想要创建两个Lists:一个包含所有元素,SomeClass一个包含所有不属于的元素SomeClass.
val a = x collect {case y:SomeClass => y}
val b = x filterNot {_.isInstanceOf[SomeClass]}
Run Code Online (Sandbox Code Playgroud)
现在我的代码看起来像那样.然而,它不是非常有效,因为它迭代x两次,代码似乎有点hackish.是否有更好(更优雅)的做事方式?
可以假设SomeClass没有子类.
我目前正在尝试将一些Java代码转换为Scala代码.挑战在于确保转换后的Scala代码与原始Java代码相比,最终不会做出非常低效的事情.例如,当尝试转换以下代码时:
class Person {
String name;
Integer age;
Character gender;
}
public class TestJava {
public static void main(String[] args) {
final List<Person> persons = new ArrayList<>();
final List<Person> males = new ArrayList<>();
final List<Person> aNames = new ArrayList<>();
final List<Person> seniors = new ArrayList<>();
for (final Person p: persons) {
if (p.gender == 'm') {
males.add(p);
}
if (p.age >= 60) {
seniors.add(p);
}
if (p.name.startsWith("a")) {
aNames.add(p);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于Java依赖于变异,因此该代码看起来很合理.但是,现在我想将它转换为Scala等价物而不会多次循环遍历该集合(在这种情况下为3次).
我当然可以使用List …
我有一个可迭代的数组,我试图将其转换为 case 类,并且我正在映射它们以执行此操作。如果数组不可转换为 case 类,我想记录警告并继续映射。但是,当我实施警告时,返回类型更改Iterable[MyCaseClass]为Iterable[Any]which 不是我想要的。例如:
case class MyCaseClass(s1: String, s2: String)
object MyCaseClass {
def apply(sa: Array[String]) = new MyCaseClass(sa(0), sa(1))
}
val arrayIterable: Iterable[Array[String]] = Iterable(Array("a", "b"), Array("a", "b", "c"))
def badReturnType(): Iterable[Any] = { // Iterable[Any] is undesireable
arrayIterable map {
case sa: Array[String] if sa.length == 2 => MyCaseClass(sa)
case _ => println("something bad happened!") // but warnings are good
}
}
def desiredReturnType(): Iterable[MyCaseClass] = { // Iterable[MyCaseClass] is desireable
arrayIterable …Run Code Online (Sandbox Code Playgroud)