Возврат элемента из списка в Scala - PullRequest
16 голосов
/ 10 сентября 2008

Я недавно работал над проектом для начинающих в Scala, и у меня есть вопрос для начинающих о списках Scala.

Скажем, у меня есть список кортежей (например, List[Tuple2[String, String]]). Существует ли удобный метод для возврата первого вхождения указанного кортежа из списка, или необходимо выполнить итерацию списка вручную?

Ответы [ 7 ]

13 голосов
/ 14 сентября 2008
scala> val list = List(("A", "B", 1), ("C", "D", 1), ("E", "F", 1), ("C", "D", 2), ("G", "H", 1))
list: List[(java.lang.String, java.lang.String, Int)] = List((A,B,1), (C,D,1), (E,F,1), (C,D,2), (G,H,1))

scala> list find {e => e._1 == "C" && e._2 == "D"}
res0: Option[(java.lang.String, java.lang.String, Int)] = Some((C,D,1))
6 голосов
/ 10 сентября 2008

Вы можете попробовать использовать find . (Обновлено местоположение scala-doc для поиска)

3 голосов
/ 16 сентября 2008

Как упоминалось в предыдущем комментарии, find, вероятно, самый простой способ сделать это. На самом деле в коллекциях Scala есть три разных метода «линейного поиска», каждый из которых возвращает немного другое значение. Какой из них вы используете, зависит от того, для чего вам нужны данные. Например, нужен ли вам индекс, или вам просто нужен логический true / false?

2 голосов
/ 11 сентября 2008

Если вы изучаете scala, я бы внимательно посмотрел на черту Seq . Он обеспечивает основу для большей части функционального совершенства scala.

1 голос
/ 28 сентября 2015

Рассмотрим collectFirst, который поставляет Some[(String,String)] для первого соответствующего кортежа или None в противном случае, например, следующим образом:

xs collectFirst { case t@(a,_) if a == "existing" => t }
Some((existing,str))

scala> xs collectFirst { case t@(a,_) if a == "nonExisting" => t }
None

Используя @, мы привязываем значение кортежа к t, чтобы можно было собрать весь соответствующий кортеж.

1 голос
/ 09 ноября 2012

Вот код, который может вам помочь.

У меня был похожий случай, когда у меня была коллекция записей базового класса (здесь A), из которых я хотел найти узел определенного производного класса, если он есть (здесь B).

class A

case class B(val name: String) extends A

object TestX extends App {
  val states: List[A] = List( B("aa"), new A, B("ccc") )

  def findByName( name: String ): Option[B] = {
    states.find{
      case x: B if x.name == name => return Some(x)
      case _ => false
    }
    None
  }

  println( findByName("ccc") )    // "Some(B(ccc))"
}

Важной частью (для моего приложения) является то, что findByName возвращает не Option[A], а Option[B].

Вы можете легко изменить поведение, чтобы вместо этого возвращать B, и выдать исключение, если ничего не было найдено. Надеюсь, это поможет.

1 голос
/ 25 декабря 2008

Вы также можете сделать это, что не требует знания имен полей в классе Tuple2 - вместо этого используется сопоставление с шаблоном:

list find { case (x,y,_) => x == "C" && y == "D" }

«найти» - это хорошо, когда вы знаете, что вам нужен только один; если вы хотите найти все подходящие элементы, вы можете использовать «фильтр» или эквивалентный сахар для понимания:

for ( (x,y,z) <- list if x == "C" && y == "D") yield (x,y,z)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...