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. 用户未指定的字段将作为通配符输入。

Val l 给我带来了麻烦。我走的是正确的路线还是有更好的方法来做到这一点?

谢谢!

4

3 回答 3

4

天哪,从哪里开始。我会首先获得一个 IDE(IntelliJ / Eclipse),它会告诉你什么时候写废话以及为什么。

阅读如何List工作。这是一个不可变的链表,因此您尝试按索引进行更新是非常错误的。

不要使用元组 - 用例类。

你永远不需要使用null,我猜你的意思是Nil.

不要使用varand while- 使用 for 表达式,或相关的高阶函数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
}
于 2013-07-15T23:10:22.517 回答
1

不确定要对结果列表做什么,但不能创建这样的通配符列表。

你想对结果列表做什么,它应该是什么类型?

如果您希望结果为 List[String],并且如果您希望通配符为“*”,则可以使用以下方法构建一些东西:

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
}
于 2013-07-15T23:00:54.257 回答
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)

,或者直接使用地图。

于 2013-07-15T23:06:09.853 回答