def doubleList(noList:List[Int]) = {
val result = noList.map{ number =>
number*2
}
result
}
def halfList(noList:List[Int]) = {
val result = noList.map{ number =>
number/2
}
result
}
def mapFunctionDRY(noList:List[Int])(codeBlock: () => Int) = {
}
println(halfList(List(1,2,3)))
println(doubleList(List(1,2,4)))
我正在玩scala并注意到上述两个函数doubleList
和halfList
中的DRY(不要重复自己)。我希望函数中的公共代码被隔离,只需传递不同的代码块。这样我的代码就不会违反DRY原则。我知道你可以在scala中传入代码块作为参数。这就是我打算在mapFunctionDRY
我希望mapFunctionDRY以这种方式
def mapFunctionDRY(noList:List[Int])(codeBlock: () => Int) = {
noList.map{ number =>
codeBlock()
}
}
doubleList
和halfList
中的代码与此类似
def doubleList(noList:List[Int]) = { mapFunctionDRY(noList){ () => number*2 } }
但如果我这样做,我会得到编译错误。在这种情况下,如何将代码作为参数传入,以避免违反DRY。可以进一步减少此代码以使其干燥吗?
答案 0 :(得分:5)
你不需要重新发明地图确实很干的工作:
def double(x: Int) = x * 2
def half(x: Int) = x / 2
val xs = List(1,2,3,4)
xs.map(double)
// List[Int] = List(2, 4, 6, 8)
xs.map(half)
// List[Int] = List(0, 1, 1, 2)
答案 1 :(得分:2)
发生编译错误是因为您希望将每个Int映射到另一个Int。 codeBlock: () => Int
是一个不带参数的函数。
codeBlock: Int => Int
应该做你想做的事。然后你可以定义这样的东西:
def doubleList(noList:List[Int]) = { mapFunctionDRY(noList){ (number : Int) => number*2 } }
虽然没有测试过。
编辑:和其他人一样说。这个函数不是很有用,因为它就像map一样,但在某种意义上它只能应用于List [Int]
答案 2 :(得分:2)
为什么要围绕map
构建一个包装器,它实际上为您的问题提供了最干净的解决方案?我建议采用不同的策略:
val mapDouble = (x: Int) => x * 2
val mapHalf = (x: Int) => x / 2
List(1, 2, 3).map(mapDouble)
List(1, 2, 3).map(mapHalf)
答案 3 :(得分:1)
您的功能在列表的一个元素上运行。因此,我会将其更改为codeBlock
,而不是() => Int
为(Int) => Int
。所以给定一个列表的一个元素你想用它做什么。
这导致以下代码:
def mapFunctionDRY(noList:List[Int])(elementFn: (Int) => Int) = {
noList.map{ number =>
elementFn(number)
}
}
如果你是短代码,那么等效代码是:
def mapFunctionDRY(noList:List[Int])(elementFn: (Int) => Int) = noList.map(elementFn)
还有很多其他方法可以保持干爽。例如,您可以单独定义操作以便能够重复使用它们:
val doubleOperation: Int => Int = _ * 2
val halfOperation: Int => Int = _ / 2
def doubleList(noList:List[Int]) = noList.map(doubleOperation)
def halfList(noList:List[Int]) = noList.map(halfOperation)
或者您可以使用函数currying来保存自己的一行代码:
def mapFunction(fn: (Int) => Int)(noList: List[Int]) = noList.map(fn)
val doubleList = mapFunction(_ * 2)
val halfList = mapFunction(_ / 2)
答案 4 :(得分:1)
我认为你在寻找的就是这方面的结论。
def func(factor:Double)(noList:List[Int]) ={
val result = noList.map{ number =>
number*factor
}
result
现在你可以用func(0.5f)(noList)或func(1.0f)(noList)传递这个函数
您甚至可以参考功能的不同版本。
halfed = x:List[Int] => func(0.5f)(x)
doubled = x:List[Int] => func(2.0f)(x)