2017-01-23 135 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) 

但它會更好地從地上爬起來重新思考它。