任意大小的元组,第一个元素类型固定

时间:2011-07-27 19:17:18

标签: scala

说我有两个清单

val L1 = List[(Int, Int)]((1,1), (2,2))
val L2 = List[(Int, Int, Int)]((1,1,1), (2,2,2))

现在我想创建一个函数func,它接受​​一个I​​nt值i以及两个列表中第一个元素匹配i的所有项。一种方法是

def func(i:Int) = {
  L1.collect.collect{case any if any._1 != i => any}
  L2.collect.collect{case any if any._1 != i => any}
}

考虑到两条线是如此相似,如果可以缩短代码将是很好的。我在某种程度上可以将L1(和L2)作为参数传递给func。该函数不应该预先知道元组将具有多少元素,只是第一个元素是Int

这可能吗?

[编辑:我认为问题不够明确。我道歉。]

这是我想要做的。我希望在两个以上的列表中执行此操作,例如n,通过多次调用func,每个列表一次。

  L1 = L1.collect.collect{case any if any._1 != i => any}
  L2 = L2.collect.collect{case any if any._1 != i => any}
  ...
  Ln = Ln.collect.collect{case any if any._1 != i => any}

其中每个L1L2,... Ln是包含第一个元素Int的元组列表

[EDIT2]

在上文中,L1可以是(Int, String)的列表,L2可以是(Int, Int, Int)等等。唯一的保证是第一个元素是{{1 }}

2 个答案:

答案 0 :(得分:6)

  def func(i:Int, lst: List[Product]) = {
    lst.filter(_.productElement(0) == i)
  }

根据您的编辑和编辑进行编辑丹的评论如上。

答案 1 :(得分:2)

任何Tuple(或者,实际上,任何案例类)都是Product,因此您可以使用产品迭代器来处理不确定大小的元组:

val x = (1,1,1,1)
x.productIterator forall {_ == 1} //returns true

由于Product是两个列表元素的常用超类型,您可以简单地连接它们并过滤:

val list1 = List((1,1), (2,2))
val list2 = List((1,1,1), (2,2,2))

(list1 ::: list2) filter {_.productIterator forall {_ == 1}}
//returns List[Product with Serializable] = List((1,1), (1,1,1))

<强>更新

仅过滤所包含产品的第一个元素上的单个列表:

val list1 = List((1,1), (2,2))
list1 filter {_.productIterator.next() == 1}