произвольный размер кортежа с фиксированным первым типом элемента - PullRequest
0 голосов
/ 27 июля 2011

Скажите, у меня есть два списка

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

Теперь я хочу создать функцию func, которая принимает значение Int 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}
}

учитывая, что эти две строки очень похожи, было бы неплохо, если бы код можно было сократить. Я думаю о том, как можно передать L1L2) в качестве параметра 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}

, где каждый L1, L2, ... Ln - это списки кортежей с первым элементом Int

[EDIT2]

В приведенном выше примере L1 может быть списком (Int, String), L2 может быть (Int, Int, Int) и т. Д. Единственная гарантия - первый элемент Int.

Ответы [ 2 ]

6 голосов
/ 28 июля 2011
  def func(i:Int, lst: List[Product]) = {
    lst.filter(_.productElement(0) == i)
  }

Отредактировано в соответствии с вашими правками и комментариями Дэна выше.

2 голосов
/ 28 июля 2011

Любой 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))

UPDATE

Чтобы отфильтровать только один список по первому элементу содержащихся продуктов:

val list1 = List((1,1), (2,2))
list1 filter {_.productIterator.next() == 1}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...