我想在scala中创建一个方法/函数,它可以接受string或int类型的变量参数,并返回String或Int类型的结果。
def Hello(name: String, Param: int*/string*): Int/String= {
var index = 0
while(index < Param.length) {
var n = name
var ar = Param(index)
if ( n.equals(ar) ) return Param(index + 1)
else index = index + 1
}
return Param(index.length -1)
}
如果我们调用Hello函数,那么它应该返回如下所示的结果。
val Res1 = Hello("Jack", "rakesh", 1, "Jack", 2, "No one")
println(Res1)
=> this should return value 2
val Res2 = Hello("ABC", "rakesh", 1, "Jack", 2, "Vik", 3, "ram", 4, "No one")
println(Res2)
=> this should return value "No one"
答案 0 :(得分:1)
这会对你有所帮助
def Hello( name: String,args: Any* ) = {
val index = args.indexOf(name)
if(index == -1)
args(args.length - 1)
else
args(index + 1)
}
答案 1 :(得分:1)
使用Any
应该有效:
def hello(name: Any, param: Any*): Any= {
var list = param.dropWhile(_ != name)
list.drop(1).headOption.orElse(param.lastOption).getOrElse("")
}
根据您希望的类型安全性,您可以尝试使用泛型或其他方法来限制使用的类型。或者您只需模式匹配响应类型:
hello("ABC", "rakesh", 1, "Jack", 2, "Vik", 3, "ram", 4, "No one") match {
case i: Int => println("Got a int:" + i)
case s: String=> println("Got a string:" + s)
}
答案 2 :(得分:1)
我相信,您想要实现的目标是在varargs中获取String
元素的索引(如果从1开始计数),或者返回"No one"
。无需将索引传递给方法。你可以这样做:
def hello(name: String, params: String*): Any = {
val idx = params.indexOf(name)
if (idx != -1) idx + 1 else "No One"
}
不幸的是this:
def Hello(name: String, args: Any* ) = {
val index = args.indexOf(name)
if(index == -1)
args(args.length - 1)
else
args(index + 1)
}
和this:
def hello(name: String, param: Any*): Any= {
var index = 0
while(index < param.length) {
var n = name
var ar = param(index)
if ( n.equals(ar) ) return param(index + 1)
else index = index + 1
}
param(index -1)
}
被破坏,因为如果你试图找到"No one"
的索引,它们会抛出异常,因为index + 1
将等于数组的大小。最好将Scala中的内容与==
进行逻辑相等比较。
但最好不要返回Any
,而是返回Option[Int]
:
def hello(name: String, params: String*): Option[Int] =
Option(params.indexOf(name)).filter(_ != -1).map(_ + 1)
那么你可以像这样使用它:
val message1 = hello("Jack", "rakesh" ,"Jack").getOrElse("No one")
val message2 = hello("ABC", "rakesh", "Jack", "Vik", "ram").getOrElse("No one")
回答评论:
我想知道如何将混合数据类型传递给&#34; param&#34;。
最简单的方法是将它们全部放在Any
并且还将字符串或整数作为返回类型
同样,将返回类型定义为Any
这里唯一的小问题是不会对其他类型进行编译时检查。例如。有人可能会将Boolean
或任何复杂对象与String
和Int
一起传递给您的函数。但您可以在运行时检查它或使用类型来限制它们。我不知道你的要求,也许这对你有利。
如果Any
没问题,我会这样解决:
def Hello(name: Any, params: Any*): Any = Option(params)
.withFilter(_.nonEmpty)
.map(_.indexOf(name))
.filter(i => i != -1 && i < params.length - 1)
.map(i => params(i + 1))
.getOrElse("No one")
或者,如果您可以认为,params
永远不会为空,您必须使用最后一个参数作为默认参数,而不仅仅是硬编码"No one"
:
def Hello(name: Any, params: Any*): Any = Option(params)
.withFilter(_.nonEmpty)
.map(_.indexOf(name))
.filter(i => i != -1 && i < params.length - 1)
.map(i => params(i + 1))
.getOrElse(params.last)
请注意针对"No one"
攻击的检查:i < params.length - 1
。
请注意,name
现在也是Any
类型。
现在,即使您将"No one"
作为name
传递,Option
也会评估为None
感谢过滤器,getOrElse
会给您1}},而不是例外。
答案 3 :(得分:1)
你的整个方法都是错误的,但这是如何以类型安全的方式完成的。
sudo tlmgr install titlesec
用法:
def Hello(name: String, param: Either[Int,String]*): Either[Int,String] = {
param.sliding(2,2)
.find(_(0).fold(_ => false, _ == name))
.fold(param.last)(_(1))
}
但最好从头开始重新考虑它。