2013-07-15 66 views
1

我想寫返回一個列表(用於查詢的目的)的功能,有一些通配符元素:如何創建通配符元素的列表斯卡拉

def createPattern(query: List[(String,String)]) = { 

    val l = List[(_,_,_,_,_,_,_)] 

    var iter = query 

    while(iter != null) { 
     val x = iter.head._1 match { 
     case "userId" => 0 
     case "userName" => 1 
     case "email" => 2 
     case "userPassword" => 3 
     case "creationDate" => 4 
     case "lastLoginDate" => 5 
     case "removed" => 6 
    } 

    l(x) = iter.head._2 
    iter = iter.tail 
    } 
    l 
} 

因此,用戶輸入一些查詢詞作爲一個列表。該功能解析這些條款並將它們插入val l。用戶未指定的字段作爲通配符輸入。

瓦爾正在給我帶來麻煩。我走的是正確的路線還是有更好的方法來做到這一點?

謝謝!

+0

'列表[(_,_,_,_,_,_,_)]'是不是值,它是一個類型。這是一個「7-tupes列表,其中每個元素都有一些明確但未知的類型」,或多或少。在這種情況下的下劃線是不受約束的存在類型的簡寫。這不太可能是你想要的。 –

回答

1

不知道你想對結果列表做什麼,但是你不能創建這樣的通配符列表。

你想對結果列表做什麼?它應該是什麼類型?

下面是你可能會建立的東西,如果你想要得到的結果是一個列表[字符串],如果你想通配符是「*」:

def createPattern(query:List[(String,String)]) = { 
    val wildcard = "*" 
    def orElseWildcard(key:String) = query.find(_._1 == key).getOrElse("",wildcard)._2 
    orElseWildcard("userID") :: 
    orElseWildcard("userName") :: 
    orElseWildcard("email") :: 
    orElseWildcard("userPassword") :: 
    orElseWildcard("creationDate") :: 
    orElseWildcard("lastLoginDate") :: 
    orElseWildcard("removed") :: 
    Nil 
} 
+0

嗨布蘭登,我打算使用結果與用戶數據庫進行比較。數據庫中的每個插入都具有每個字段的值: (userId,userName,email,userPassword,creationDate,lastLoginDate,已刪除)。搜索功能將包含要搜索的術語列表。比方說,例如,用戶搜索決定指定(電子郵件,creationDate,刪除)。我想要將數據庫中的每個用戶與這些特定字段進行匹配,但是其他所有通配符都匹配。像: '(userId,userName,email,userPassword,creationDate,lastLoginDate,已刪除)==(*,*,email,*,creationDate,*,已刪除)'? –

+0

如果要使用它來構建SQL查詢或使用某個數據庫庫的查詢,則可能會比使用通配符的字符串列表(或元組)更有用的表示。 – brandon

1

您沒有使用列表,元組,迭代器或通配符正確。 我會採取不同的方式 - 也許是這樣的:

case class Pattern (valueMap:Map[String,String]) { 
    def this(valueList:List[(String,String)]) = this(valueList.toMap) 

    val Seq(
      userId,userName,email,userPassword,creationDate, 
      lastLoginDate,removed 
     ):Seq[Option[String]] = Seq("userId", "userName", 
       "email", "userPassword", "creationDate", "lastLoginDate", 
       "removed").map(valueMap.get(_)) 
} 

然後,你可以做這樣的事情:

scala> val pattern = new Pattern(List("userId" -> "Fred")) 
pattern: Pattern = Pattern(Map(userId -> Fred)) 

scala> pattern.email 
res2: Option[String] = None 

scala> pattern.userId 
res3: Option[String] = Some(Fred) 

,或者乾脆直接使用地圖。

4

天哪,從哪裏開始。我首先得到一個IDE(IntelliJ/Eclipse),它會告訴你什麼時候寫廢話和爲什麼。

請閱讀List的工作原理。這是一個不可變的鏈表,所以你試圖通過索引進行更新是非常錯誤的。

不要使用元組 - 用例類。

你不應該永遠需要使用null我想你在這裏的意思是Nil

不要使用varwhile - 使用了表達,或相關的高階函數foreachmap

您的代碼並沒有太大的意義,因爲它是,但似乎你」重新嘗試返回一個7元素列表,其中輸入列表中的每個元組的第二個元素通過查找映射到輸出列表中的位置。

要改善它...不要這樣做。你在做什麼(自從數組被髮明以來,程序員已經完成了)是使用索引作爲從Int到Map的粗略代理。你想要的是一個實際的Map。我不知道你想用它做什麼,但是如果它是從這些關鍵字串本身而不是一個數字更好呢?如果是這樣,您可以簡化整個方法

def createPattern(query: List[(String,String)]) = query.toMap 

在這一點上,你應該意識到,你可能並不需要的方法在所有的,因爲你可以使用toMap在調用點。

如果你堅持使用Int指數,你可以寫

def createPattern(query: List[(String,String)]) = { 
    def intVal(x: String) = x match { 
    case "userId" => 0 
    case "userName" => 1 
    case "email" => 2 
    case "userPassword" => 3 
    case "creationDate" => 4 
    case "lastLoginDate" => 5 
    case "removed" => 6 
    } 
    val tuples = for ((key, value) <- query) yield (intVal(key), value) 
    tuples.toMap 
} 
+0

嗨路易吉,感謝您的建議!我打算用這個函數輸出一個帶有缺失項目的7tuple,這樣一個謹慎的7tuple可以像這樣進行比較:'(userId,userName,email,userPassword,creationDate,lastLoginDate,removed)==(*,*,email,*, creationDate,*,刪除)'?你認爲.toMap在這種情況下仍然有效嗎?你的模型不會爲'(*,*,email,*,creationDate,*,removed,)生成一個與'(userId,userName,email,userPassword,creationDate,lastLoginDate,removed)'非常不同的散列碼,假設'email','creationDate'和'removed'具有相同的值? –

+0

對不起,我能正確理解你嗎?對不起,如果我不清楚我的原始問題 –

+0

@Alex它看起來像你試圖重新發明輪子,在一個很奇怪的方式。如果你正在查詢一個數據庫,你應該使用SQL,或者像Slick(http://slick.typesafe.com/)這樣的庫,它可以讓你在Scala中編寫查詢。 –