匹配具有条件的列表的模式

时间:2016-11-03 18:15:47

标签: scala pattern-matching

我有一个整数列表:

val l = List(100, 200, 100)

我正在尝试对其值进行模式匹配,但规则有点复杂。

1. 100 or 200, but at least 1 100 
2. 300 or 400, with at least 1 300 and the rest 300 or 400
3. 700 or 800, with at least 1 700 and the rest 700 or 800

是否可以在模式匹配表达式中表达它?

val result: Option[String] = l match {
 case (100 | 200) ???  => "1"
 case (300 | 400) ??? => "2"
 case (700 | 800) ??? => "3"
 case _ => None
}

3 个答案:

答案 0 :(得分:1)

为了避免对每个案例O(n^2)进行详尽的检查,首先采用列表O(n)的最小元素来区分案例,并验证列表是否只有预期的元素(O(n) ))。这应该有效:

val result:Option[Int] = (l.min, l) match {
  case (100, l) if l.forall(Set(100,200)) => Some(1)
  case (300, l) if l.forall(Set(300,400)) => Some(2)
  case (700, l) if l.forall(Set(700,800)) => Some(3)
  case _ => None
}

答案 1 :(得分:1)

这是你正在寻找的逻辑吗?从你的描述中说出来有点难以理解。

PDOException : SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: '' for column 'field_image54_width' at row 1: INSERT INTO {field_data_field_image54} (entity_type, entity_id, revision_id, bundle, delta, language, field_image54_fid, field_image54_alt, field_image54_title, field_image54_width, field_image54_height) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10); Array ( [:db_insert_placeholder_0] => node [:db_insert_placeholder_1] => 24 [:db_insert_placeholder_2] => 24 [:db_insert_placeholder_3] => flexslidertest [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => 51 [:db_insert_placeholder_7] => [:db_insert_placeholder_8] => [:db_insert_placeholder_9] => [:db_insert_placeholder_10] => ) dans field_sql_storage_field_storage_write() (ligne 514 dans /home/sinus/Web/Mysite/modules/field/modules/field_sql_storage/field_sql_storage.module).

答案 2 :(得分:0)

你无法真正匹配这样的值。你可以这样做:

l match {
  case _ if l.forall(Set(100,200).contains) && l.contains(100) => Some("1")
  case _ if l.forall(Set(300,400).contains) && l.contains(300) => Some("2")
  case _ if l.forall(Set(700,800).contains) && l.contains(700) => Some("3")
  case _ => None
}

虽然不是最有效的,因为你每个案例都要遍历两次列表。使用某种形式的foldLeft可以更有效地完成它。