在Scala中将字符串转换为运算符
Posted
技术标签:
【中文标题】在Scala中将字符串转换为运算符【英文标题】:Convert string into operator in Scala 【发布时间】:2016-03-26 02:22:10 【问题描述】:如何将 Scala 中的字符串转换为相应的运算符? 给定两个整数和字符串“+”,我想要这两个整数相加的结果。
【问题讨论】:
【参考方案1】:最后一个问题很简单:
def applyOperator(x: Int, y: Int, operator: String) = operator match
case "+" => x + y
case "-" => x - y
...
您可以尝试使用 Twitter 的 Eval 库或反射,但考虑到更简单的解决方案,我不推荐它。
对于第一个问题:运算符本身不是值,因此您不能“将字符串转换为运算符”。但是您可以接近:将字符串转换为将添加(或减去等)其参数的函数:
def stringToOperator(operator: String): (Int, Int) => Int = operator match
case "+" => _ + _
case "-" => _ - _
...
您甚至可以将其概括为不仅仅适用于整数:
def stringToOperator[A: Numeric](operator: String): (A, A) => A = operator match ...
(这显然也适用于第一个答案。)
【讨论】:
请您为第一个代码添加一些解释。孤独的代码什么也没说。 我已经扩展了一些答案。【参考方案2】:这个
case class Evaluatee(v1: Int, operator: String, v2: Int)
object Evaluator
def raw(s: String)(v1: Int, v2: Int) = s match
case "+" => (v1 + v2)
case "-" => (v1 - v2)
case "*" => (v1 * v2)
case "/" => (v1 / v2)
def evaluate(evaluatee: Evaluatee) =
raw(evaluatee.operator)(evaluatee.v1, evaluatee.v2)
完成了这个测试:
test("1+1=2")
assert(Evaluator.evaluate(Evaluatee(1, "+", 1)) == 2)
test("2-1=1")
assert(Evaluator.evaluate(Evaluatee(2, "-", 1)) == 1)
test("1+1=2 raw")
assert(Evaluator.raw("+")(1,1) == 2)
【讨论】:
【参考方案3】:我们不能只做类似1 "+" 2
的事情,因为我认为 scala 的最大特点是可以创建自己的DSL
是 apply
方法,但我不能一无所有地调用它,我很确定我们总是需要使用()
或 例如
List(1)
我们不能使用List 1
但我们可以使用List1
。
但试试这个也许对你有用
case class NumOp (num1:Int)
def apply(op:String)(num2:Int):Int =
op match
case "+" => num1+num2
case "-" => num1-num2
case _ => 0
object ConvertsNumOp
implicit def convert(a:Int):NumOp= NumOp(a)
import ConvertsNumOp._
scala> 2 ("-") (1)
res0: Int = 1
scala> 4 ("-") (2)
res1: Int = 2
scala> 4 ("+") (2)
res2: Int = 6
scala> 4 ("-") (2) ("+") (1) ("-") (8)
res0: Int = -5
你可以动态地做事,所以也许可以工作。
已编辑:
这是另一个版本的NumOp
可能是最干净的
case class NumOp(num1:Int)
def apply(op:String):Int => Int =
op match
case "+" => num1.+_
case "-" => num1.-_
case _ => throw new NotImplementedError("Operator not implemented")
动态使用
val numList = List(1,2,3,4,5,6,7,8,9,10);
val optList = List("+","-");
var retVal = for a <- numList; op <- optList
yield (a)(op)(a)
【讨论】:
以上是关于在Scala中将字符串转换为运算符的主要内容,如果未能解决你的问题,请参考以下文章
在scala中将spark决策树模型调试字符串转换为嵌套JSON
如何在 Scala(Spark 2.0)中将带有字符串的 DataFrame 转换为带有 Vectors 的 DataFrame