2017-01-23 102 views
0

我想在scala中创建一个方法/函数,它可以接受string或int类型的可变参数并返回String或Int类型的结果。将可变参数数据类型传递给scala方法

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

可能会使用'Any'可能会有帮助,但不是确切吗? 'def func1(a:String,s:任何*):任何' –

+1

你有没有考虑过? 'def Hello(name:String,Param:E [Array [Int]/Array [String]]):[Int/String]'?你可以将它重载为可变参数,并且在'Either'中有共同的代码。 –

回答

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) 
} 
+0

1.这种情况没有编译: val Res3 = Hello(5,rakesh,1,Jack,2,Vik,vinccent,ram,4,5 ,“Five”,“No one”)==>返回“five”''' - [见第一条评论](http://stackoverflow.com/a/41813212/5100014)。 2.在这种情况下抛出异常: '''Hello(“No one”,“rakesh”,1,“Jack”,2,“Vik”,3,“ram”,4,“No one”) ''' – zhelezoglo

+0

@zhelezoglo看到我更新的答案,我简化了代码。当它找不到元素时,我返回最后一个元素。不知道是否要将其更改为其他参数 – nmat

1

这将帮助你

def Hello(name: String,args: Any*) = { 

     val index = args.indexOf(name) 
     if(index == -1) 
     args(args.length - 1)    
     else 
     args(index + 1) 

} 
1

我相信,你想达到什么样的,是得到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") 

接听评论:

我想kn如何将混合数据类型传递给“参数”。

最简单的办法是让他们所有类型Any

的,也得到字符串或整数返回类型

用同样的方法,定义返回类型为Any

这里唯一的一个小问题是没有编译时检查其他类型。例如。有人可能会将Boolean或任何复杂对象与StringInt一起传递给您的函数。但是你可以在运行时检查它,或者使用类型来限制它们。我不知道你的要求,也许这对你有好处。

如果有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是从来没有空,你必须使用上次PARAM作为默认值,而不是只是硬编码"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会给你默认"No one",而不是例外。

+0

“param”的变量参数可以是我的需求中的字符串或整数,所以我想知道如何传递字符串或整数,并获取字符串或整数作为返回类型,基于对我的程序的输入。 我的“参数”列表有字符串和整数类型。 我想知道如何将混合数据类型传递给“参数”。 val Res2 = Hello(“Vik”,“rakesh”,1,“Jack”,2,“Vik”,“vinccent”,“ram”,4,“No one”) ==> return“vinccent” val Res3 = Hello(5,“rakesh”,1,“Jack”,2,“Vik”,“vinccent”,“ram”,4,5,“Five”,“No one”) ==>返回“五” – vikv

+0

我修改了解决您评论的答案。我很抱歉,我的第一个猜测是错误的。顺便说一下,它是必需的,你可以传递_only_ Int或String的,它应该在编译时检查? – zhelezoglo

1

你的整个方法是错误的,但这是如何以类型安全的方式完成的。

def Hello(name: String, param: Either[Int,String]*): Either[Int,String] = { 
    param.sliding(2,2) 
     .find(_(0).fold(_ => false, _ == name)) 
     .fold(param.last)(_(1)) 
} 

用法:

Hello("Jack", Right("rakesh"), Left(1), Right("Jack"), Left(2), Right("No one")) 
// res0: Either[Int,String] = Left(2) 

Hello("ABC", Right("rakesh"), Left(1), Right("Jack"), Left(2), 
      Right("Vik"), Left(3), Right("ram"), Left(4), Right("No one")) 
// res1: Either[Int,String] = Right(No one) 

但它会更好地从地上爬起来重新思考它。