스칼라 목록에있는 아이템을 얻으시겠습니까?


205

세계의 스칼라 목록 에서 인덱스 i 의 요소를 어떻게 얻 습니까?

나는 시도 get(i)하고 [i]- 아무것도 작동하지 않습니다. 인터넷 검색은 목록에서 요소를 "찾는"방법 만 반환합니다. 그러나 나는 이미 요소의 색인을 알고 있습니다!

컴파일되지 않은 코드는 다음과 같습니다.

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

  }
  return null
}

내 눈이 그냥 교차하기 때문에 List api를 보는 것이 도움이되지 않습니다.


1
글쎄, data.head가 효과가있는 것처럼 보입니다 ...하지만 여전히 목록의 요소가 아닌 첫 번째 요소 만 제공합니다.
Andriy Drozdyuk

인덱스가 범위를 벗어난 것이 확실한 경우 Seq 특성 apply (index)를 사용하십시오 . scala-lang.org/api/current/…
Beezer

data.drop (i) .head는 i 번째 요소에 액세스하는 데 사용
Vinay

@Vinay 비용이 많이 드는 작업입니다. 따라서 "drop (i) .head"를 피해야합니다.
Shubham Agrawal

답변:


305

괄호를 사용하십시오.

data(2)

그러나 연결된 목록을 탐색하는 데 시간이 걸리기 때문에 목록을 사용하여 자주 그렇게하지 않으려는 경우 컬렉션으로 색인을 생성하려면 Vector(불변) 또는 ArrayBuffer(변경 가능) 또는 가능하면 Array(Java 배열 일 뿐이며을 (i)대신하여 색인을 생성하는 것을 제외하고 [i]) 가능합니다.


1
기본적으로 Java에서 ArrayList와 같은 것을 찾고 있습니다. 불변도 괜찮을 것 같아요.
Andriy Drozdyuk

1
ArrayBuffer처럼 작동합니다 ArrayList. Vector불변처럼 작동합니다. ArrayList읽을 수는 있지만 새로 만들지 않으면 쓸 수 없습니다.
렉스 커

하위 목록은 어떻습니까? 예를 들어 Java에서는 "data.subList (0, index)"를 수행합니다.
Andriy Drozdyuk

신경 쓰지 마, 알았어- "슬라이스"야! ArrayBuffer를 Vector로 변환 할 수 있습니까? 아니면 메소드에서 반환 할 수있는보다 일반적인 유형이 있습니까? 예를 들어 Java에서는 List 인터페이스를 반환합니다.
Andriy Drozdyuk

1
를 사용하여 로 변환 ArrayBuffer할 수 있습니다 . 더 일반적인 유형입니다. (이 경우 실제로는로 구현되는 것으로 판명되었습니다 .) 색인을 생성 할 수있는 컬렉션의 상위 유형입니다. 또한, 할 수 있으며 거의 ​​모든 컬렉션 (양쪽)에서 작동합니다. 왼쪽에있는 하나의 유형을 유지하면서 지정한 두 가지로부터 새로운 컬렉션을 만듭니다. 빈 벡터이므로 원하는 것을 생성합니다. IndexedSeq.toIndexedSeqIndexedSeqVectorIndexedSeqVector() ++ myArrayBuffer++Vector()
렉스 커

121

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에 래핑 하여 부분 함수 (일부 입력에 대해서만 정의 된 기능)를 일반 함수 (모든 입력에 대해 정의 된)로 변환합니다.


11
리프트가 아름답습니다. 배열의 크기를 확인하지 않고 arrayIndexOutOfBound 오류를 피할 수 있습니다.
Naveen Sachar

9

왜 괄호입니까?

다음은 scala 의 책 프로그래밍에서 인용 한 것입니다 .

이 예제에서 설명하는 또 다른 중요한 아이디어는 스칼라에서 괄호로 배열에 액세스하는 이유에 대한 통찰을 제공합니다. 스칼라는 Java보다 특별한 경우가 적습니다. 배열은 스칼라의 다른 클래스와 마찬가지로 단순히 클래스의 인스턴스입니다. 하나 이상의 값을 둘러싼 괄호를 변수에 적용하면 Scala는 해당 변수에 apply라는 메소드를 호출하여 코드를 변환합니다. 따라서 greetStrings (i)는 greetStrings.apply (i)로 변환됩니다. 따라서 스칼라에서 배열의 요소에 액세스하는 것은 다른 것과 마찬가지로 단순히 메소드 호출입니다. 이 원칙은 배열로 제한되지 않습니다. 괄호 안의 일부 인수에 객체를 적용하면 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)


0

이것은 요즘 색인을 통해 List의 데이터에 액세스하는 선호되는 방법입니다.

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

그러나 위에서 언급 한 Rex Kerr와 같이 : 인덱스를 사용하는 경우 List 대신 Vector를 사용해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.