2013-07-15 69 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中编写查询。 –