Возврат элемента из списка в Scala

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

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


person Community    schedule 10.09.2008    source источник


Ответы (7)


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

person Tim Sullivan    schedule 10.09.2008

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

person Daniel Spiewak    schedule 15.09.2008
comment
Не могли бы вы дать больше информации об этих методах линейного поиска? Я хочу получить индекс кортежа (имеющий только часть кортежа) - person krookedking; 15.04.2014
comment
на самом деле я нашел то, что искал: .zipWithIndex.collect { case ("partOfTuple", _, i) => i } - person krookedking; 15.04.2014

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

person sblundy    schedule 11.09.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)
person Community    schedule 24.12.2008
comment
Ваш второй пример, похоже, работает гораздо больше, чем filter, т. е. он вернет все элементы, соответствующие свойству, а не только первый, как того хочет автор вопроса. - person Dmitry Volosnykh; 24.05.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, и выбрасывалось исключение, если ничего не было найдено. Надеюсь это поможет.

person akauppi    schedule 09.11.2012

Рассмотрим 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, чтобы можно было собрать весь совпадающий кортеж.

person elm    schedule 27.09.2015

person    schedule
comment
Можно ли вернуть не Some((C,D,1)) а (C,D,1)? Я имею в виду то же самое, если бы я использовал список (1). - person grass; 11.10.2012
comment
@grass Каким должно быть возвращаемое значение, если тройка (C,D,1) не найдена в списке? - person Binil Thomas; 11.10.2012
comment
Нет, исключение или пустой набор. Было бы здорово, если бы был способ настроить возвращаемое значение, если тройка не найдена (кроме написания моего собственного метода find()). - person grass; 12.10.2012
comment
«Ни один» и «некоторые» всегда идут вместе. Они делают «Вариант [T]». Если бы ваша функция просто возвращала 'T', вы должны сигнализировать об отсутствии такого случая с помощью исключения. Я скоро добавлю ответ, который, я думаю, дает то, что вы хотите (используя «найти»). - person akauppi; 09.11.2012