如何创建一个通配符元素列表Scala

时间:2013-07-15 21:52:23

标签: scala wildcard

我正在尝试编写一个返回列表(用于查询目的)的函数,该函数包含一些通配符元素:

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给我带来了麻烦。我是走正确的路线还是有更好的方法来做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:4)

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

了解List的工作原理。它是一个不可变的链表,因此您按索引更新的尝试是非常错误的。

不要使用元组 - 用例类。

您不应该使用null,我想你的意思是Nil

请勿使用varwhile - 使用for-expression,或使用相关的高阶函数foreachmap等。

你的代码并没有多大意义,但似乎你正在尝试返回一个7元素列表,其中每个元组的第二个元素在输入列表中通过查找映射到位置在输出列表中。

改善它......不要那样做。你正在做的事情(正如程序员自阵列发明以来所做的那样)是使用索引作为从Int到任何地图的粗略代理。你想要的是一个实际的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
}

答案 1 :(得分: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
}

答案 2 :(得分:1)

您没有正确使用List,Tuple,iterator或wild-cards。 我会采取不同的方法 - 可能是这样的:

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)

,或直接使用地图。