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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
16
0
26 622
7

Ответы 7

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

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

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))

Можно ли вернуть не Some ((C, D, 1)), а (C, D, 1)? Я имею в виду то же самое, если бы я использовал list (1).

grass 11.10.2012 01:41

@grass Каким должно быть возвращаемое значение, если тройной (C,D,1) нет в списке?

Binil Thomas 11.10.2012 11:38

Нет, или исключение, или пустой набор. Было бы здорово, если бы был способ настроить возвращаемое значение, если тройка не найдена (кроме написания моего собственного метода find ()).

grass 12.10.2012 12:24

«Нет» и «Некоторые» всегда идут вместе. Они делают «Вариант [T]». Если ваша функция должна просто возвращать "T", вы должны сигнализировать об отсутствии такого случая с помощью исключения. Я скоро добавлю ответ, который, как мне кажется, обеспечивает то, что вы хотите (с помощью 'find').

akauppi 09.11.2012 13:21

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

Не могли бы вы подробнее рассказать об этих методах «линейного поиска»? Я хочу получить индекс кортежа (имеющего только часть кортежа)

krookedking 15.04.2014 13:58

на самом деле я нашел то, что искал: .zipWithIndex.collect { case ("partOfTuple", _, i) => i }

krookedking 15.04.2014 14:10

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

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

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

for ( (x,y,z) <- list if x == "C" && y == "D") yield (x,y,z)

Ваш второй пример, похоже, больше похож на filter, то есть он вернет свойство соответствия элементов все, а не единственное первое, как того хочет автор вопроса.

Dmitry Volosnykh 24.05.2012 21:44

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

У меня был аналогичный случай, когда я имел коллекцию записей базового класса (здесь 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 и генерировать исключение, если ничего не найдено. Надеюсь это поможет.

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

Другие вопросы по теме