Я пытаюсь понять, как лучше это написать.
у меня есть Список и СписокB.
val ListA: List[((String, String), Int)] = List(
(("A", "B"), 1),
(("C", "D"), 2),
(("E", "F"), 5),
(("E", "F"), 4),
(("E", "F"), 3)
)
val ListB: List[(String, String)] = List(
("A", "B"),
("E", "F")
)
Нам нужно искать id в Список которые содержат СписокB элемент. Например, кортеж («A», «B») присутствует в ListA с ((«A», «B»), 1),. так что вывод будет Список (1). Этот процесс повторится снова, как только мы получим первое совпадение. если совпадений не найдено, то Список (0) будет выводиться. Я написал это.
val result = ((for {
a <- ListB
m <- ListA.filter(_._1 == a).map(_._2)
} yield m):::List(0)).slice(0,1)
slice используется, потому что нам нужен список с первым совпадением. в качестве СписокB уже отсортирован по приоритету. Также мы собираемся повторить этот процесс еще раз, удалив уже совпавший идентификатор из Список. Но пока, пожалуйста, не обращайте внимания на то, как мы удаляем эти элементы и повторяем заново.
Итак, новая итерация будет на
val ListA: List[((String, String), Int)] = List(
// (("A", "B"), 1), This will not be part of second iteration as we already matched it in first iteration.
(("C", "D"), 2),
(("E", "F"), 5),
(("E", "F"), 4),
(("E", "F"), 3)
)
val ListB: List[(String, String)] = List(
("A", "B"),
("E", "F")
)
Выход
- итерация 1 Список (1)
- итерация 2 Список (5)
- итерация 3 Список (4)
- итерация 4 Список (3)
- итерация 5 Список (0)
Я просто хотел бы понять это
«Это правильный способ кодирования, при котором мы ищем один элемент списка в другом».
«У нас есть какая-нибудь библиотека scala, которую можно использовать здесь, например ListA.filter (ListB.contains (_._ 1)) -> для этого нам нужно написать метод полного фильтра, чтобы он не работал так»
1 ответ
Помимо моего комментария, я бы предложил использовать Set for, well, наборы, поскольку операции, вероятно, будут быстрее, но, что более важно, они более правильные по отношению к. какие операции с ними можно делать.
val setB: Set[(String, String)] = ListB.toSet
val filtered: List[((String, String), Int)] =
ListA.filterNot(x => setB.contains(x._1))
val result: List[Int] =
filtered.map(_._2)
Это возвращает другой результат. Как я написал в своем комментарии, я не совсем понимаю причины, лежащие в основе алгоритма, и если это реальное требование, чтобы он был итеративным, как этот, вам, вероятно, придется использовать реализацию, которая у вас есть прямо сейчас, то есть через for.
Кроме того, разделение вычислений на несколько этапов может помочь понять, что происходит (особенно в отладчике), поэтому я скопировал сигнатуры типов, как и вы.
Если требуется точно такой же результат, тогда это было бы так:
val result = ((for {
m <- ListA.filter(x => setB.contains(x._1)).map(_._2)
} yield m):::List(0)).slice(0,1)
- Также переменные не должны начинаться с верхнего регистра, ср.
setBвместоSetB.
