在数组上执行循环操作的功能方法
Functional way of doing a loop of operations on an array
我目前有一个 Java 程序,它执行如下操作:
int nvars = 10;
long vars[] = new long[nvars];
for(int i = 0; i < nvars; i++) {
vars[i] = someFunction(i);
anotherFunction(vars[i]);
}
我正在将它转换为 Scala 代码并具有:
val nvars: Int = 10
val vars: Array[Long] = new Array[Long](nvars)
for ( i <- 0 to nvars-1 )
vars(i) = someFunction(i)
anotherFunction(vars(i))
}
关于如何使这个(更多)功能有任何建议吗?
Array伴生对象中有很多有用的构造方法,比如你这里的情况,可以使用tabulate
:
val nvars: Int = 10
val vars = Array.tabulate(nvars){ someFunction } // calls someFunction on the values 0 to nvars-1, and uses this to construct the array
vars foreach (anotherFunction) // calls anotherFunction on each entry in the array
如果 anotherFunction
returns 是一个结果而不仅仅是一个 "side-effect" 函数,您可以通过调用 map
:
来捕获它
val vars2 = vars map (anotherFunction) // vars2 is a new array with the results computed from applying anotherFunction to each element of vars, which is left unchanged.
考虑迭代 Long
个值的范围,
val vars = (1L to 10L).map(someFunction).map(anotherFunction)
这会将 someFunction
应用于范围中的每个值,然后将第一个 map
的每个中间结果应用于 anotherFunction
。假设每个函数接受并传递类型为 Long
.
的值
要将 vars
转换为所需的集合,例如 Array
或 List
,请考虑,
vars.toArray
vars.toList
使用 view
将两个函数同时应用于范围内的每个值,因此不必从映射 someFunction
、
创建中间集合
(1L to 10L).view.map(someFunction).map(anotherFunction)
使用map
。在 Array
上调用映射将 return 一个新集合。因此,为每个要应用于 Array
.
的所有元素的函数调用 map
两次
一些简单的功能演示:
scala> def addOne(l: Long) = l + 1
addOne: (l: Long)Long
scala> def addTwo(l: Long) = l + 2
addTwo: (l: Long)L
map
数组 vars
使用定义的函数。
scala> val vars = Array[Long](1,2,3,4,5,6,7,8,9,10)
vars: Array[Long] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> vars.map(addOne(_))
res0: Array[Long] = Array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
scala> vars.map(addOne(_)).map(addTwo(_))
res1: Array[Long] = Array(4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
另一种 "more functional" 方法可能是一个很好的练习,它是使用递归函数,该函数将函数作为参数并将传入的函数应用于 List
的每个元素。
scala> def fun[A](as: List[A], f: A => A): List[A] = as match {
| case List() => List()
| case h::t => f(h) :: fun(t, f)
| }
fun: [A](as: List[A], f: A => A)List[A]
我目前有一个 Java 程序,它执行如下操作:
int nvars = 10;
long vars[] = new long[nvars];
for(int i = 0; i < nvars; i++) {
vars[i] = someFunction(i);
anotherFunction(vars[i]);
}
我正在将它转换为 Scala 代码并具有:
val nvars: Int = 10
val vars: Array[Long] = new Array[Long](nvars)
for ( i <- 0 to nvars-1 )
vars(i) = someFunction(i)
anotherFunction(vars(i))
}
关于如何使这个(更多)功能有任何建议吗?
Array伴生对象中有很多有用的构造方法,比如你这里的情况,可以使用tabulate
:
val nvars: Int = 10
val vars = Array.tabulate(nvars){ someFunction } // calls someFunction on the values 0 to nvars-1, and uses this to construct the array
vars foreach (anotherFunction) // calls anotherFunction on each entry in the array
如果 anotherFunction
returns 是一个结果而不仅仅是一个 "side-effect" 函数,您可以通过调用 map
:
val vars2 = vars map (anotherFunction) // vars2 is a new array with the results computed from applying anotherFunction to each element of vars, which is left unchanged.
考虑迭代 Long
个值的范围,
val vars = (1L to 10L).map(someFunction).map(anotherFunction)
这会将 someFunction
应用于范围中的每个值,然后将第一个 map
的每个中间结果应用于 anotherFunction
。假设每个函数接受并传递类型为 Long
.
要将 vars
转换为所需的集合,例如 Array
或 List
,请考虑,
vars.toArray
vars.toList
使用 view
将两个函数同时应用于范围内的每个值,因此不必从映射 someFunction
、
(1L to 10L).view.map(someFunction).map(anotherFunction)
使用map
。在 Array
上调用映射将 return 一个新集合。因此,为每个要应用于 Array
.
map
两次
一些简单的功能演示:
scala> def addOne(l: Long) = l + 1
addOne: (l: Long)Long
scala> def addTwo(l: Long) = l + 2
addTwo: (l: Long)L
map
数组 vars
使用定义的函数。
scala> val vars = Array[Long](1,2,3,4,5,6,7,8,9,10)
vars: Array[Long] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> vars.map(addOne(_))
res0: Array[Long] = Array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
scala> vars.map(addOne(_)).map(addTwo(_))
res1: Array[Long] = Array(4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
另一种 "more functional" 方法可能是一个很好的练习,它是使用递归函数,该函数将函数作为参数并将传入的函数应用于 List
的每个元素。
scala> def fun[A](as: List[A], f: A => A): List[A] = as match {
| case List() => List()
| case h::t => f(h) :: fun(t, f)
| }
fun: [A](as: List[A], f: A => A)List[A]