Получить элемент в списке в Scala?

123

Как в мире вы получаете только элемент в индексе i из списка в scala?

Я пробовал get(i), а [i] - ничего не работает. Googling возвращает только то, как "найти" элемент в списке. Но я уже знаю индекс элемента!

Вот код, который не компилируется:

def buildTree(data: List[Data2D]):Node ={
  if(data.length == 1){
      var point:Data2D = data[0]  //Nope - does not work

  }
  return null
}

Глядя на Список api не помогает, так как мои глаза просто пересекаются.

  • 1
    Что ж, похоже, data.head сработал ... Но все же это дает мне только первый элемент, а не кого-то в списке.
  • 0
    Используйте черты Seq apply (index), если вы уверены, что индекс не выходит за пределы. scala-lang.org/api/current/...
Показать ещё 2 комментария
Теги:

3 ответа

196
Лучший ответ

Используйте круглые скобки:

data(2)

Но вы не очень хотите делать это со списками очень часто, так как связанным спискам требуется время, чтобы пройти. Если вы хотите индексировать в коллекцию, используйте Vector (неизменяемый) или ArrayBuffer (изменяемый) или, возможно, Array (который является всего лишь массивом Java, за исключением того, что вы индексируете его с помощью (i) вместо [i]).

  • 1
    В основном я ищу что-то вроде ArrayList в Java. Я думаю, что неизменный тоже будет хорошо.
  • 1
    ArrayBuffer работает как ArrayList . Vector работает как неизменяемый ArrayList вы можете читать, но вы не можете писать без создания нового.
Показать ещё 5 комментариев
69

Безопаснее использовать lift, чтобы вы могли извлечь значение, если оно существует, и изящно терпеть неудачу, если это не так.

data.lift(2)

Это приведет к возврату None, если список недостаточно длинный, чтобы предоставить этот элемент, а Some (value), если он есть.

scala> val l = List("a", "b", "c")
scala> l.lift(1)
Some("b")
scala> l.lift(5)
None

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

Объяснение:

Это работает, потому что List apply (который содержит только скобки, например l(index)), как частичная функция, которая определяется везде, где список имеет элемент. Метод List.lift превращает частичную функцию apply (функцию, определенную только для некоторых входов) в нормальную функцию (определенную для любого ввода), в основном обертывая результат в Option.

  • 5
    Лифт прекрасен. Я могу избежать ошибок arrayIndexOutOfBound, не проверяя размер массива.
8

Почему скобки?

Вот цитата из книги программирование в scala.

Другая важная идея, проиллюстрированная этим примером, даст вам представление о том, почему массивы доступны с круглыми скобками в Scala. Scala имеет меньше особых случаев, чем Java. Массивы - это просто экземпляры классов, подобных любому другому классу в Scala. Когда вы применяете круглые скобки, связанные с одним или несколькими значениями для переменной, Scala преобразует код в вызов метода с именем apply для этой переменной. Поэтому greetStrings (i) преобразуется в greetStrings.apply(i). Таким образом, доступ к элементу массива в Scala - это просто вызов метода, как любой другой. Этот принцип не ограничивается массивами: любое приложение объекта к некоторым аргументам в круглых скобках будет преобразовано в вызов метода apply. Конечно, это скомпилируется, только если этот тип объекта фактически определяет метод apply. Так что это не особый случай; это общее правило.

Вот несколько примеров того, как вытащить определенный элемент (в первую очередь, в этом случае), используя стиль функционального программирования.

  // Create a multdimension Array 
  scala> val a = Array.ofDim[String](2, 3)
  a: Array[Array[String]] = Array(Array(null, null, null), Array(null, null, null))
  scala> a(0) = Array("1","2","3")
  scala> a(1) = Array("4", "5", "6")
  scala> a
  Array[Array[String]] = Array(Array(1, 2, 3), Array(4, 5, 6))

  // 1. paratheses
  scala> a.map(_(0))
  Array[String] = Array(1, 4)
  // 2. apply
  scala> a.map(_.apply(0))
  Array[String] = Array(1, 4)
  // 3. function literal
  scala> a.map(a => a(0))
  Array[String] = Array(1, 4)
  // 4. lift
  scala> a.map(_.lift(0))
  Array[Option[String]] = Array(Some(1), Some(4))
  // 5. head or last 
  scala> a.map(_.head)
  Array[String] = Array(1, 4)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню