Dapatkan item dalam daftar di Scala?


205

Bagaimana di dunia Anda mendapatkan hanya elemen di indeks saya dari Daftar di scala?

Saya mencoba get(i), dan [i]- tidak ada yang berhasil. Googling hanya mengembalikan cara "menemukan" elemen dalam daftar. Tapi saya sudah tahu indeks elemen!

Berikut adalah kode yang tidak dikompilasi:

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

  }
  return null
}

Melihat api Daftar tidak membantu, karena mataku hanya menyeberang.


1
Yah well, sepertinya data.head berfungsi ... Tapi tetap saja itu hanya memberi saya elemen pertama, tidak ada satu pun dalam daftar.
Andriy Drozdyuk

Gunakan ciri Seq berlaku (indeks) jika Anda yakin indeks tidak keluar batas. scala-lang.org/api/current/…
Beezer

data.drop (i) .head berfungsi untuk mengakses elemen ke-i
Vinay

@ Vinay Itu operasi yang mahal. Jadi seseorang harus menghindari "drop (i) .head".
Shubham Agrawal

Jawaban:


305

Gunakan tanda kurung:

data(2)

Tetapi Anda tidak benar-benar ingin melakukannya dengan daftar sangat sering, karena daftar tertaut membutuhkan waktu untuk dilintasi. Jika Anda ingin mengindeks ke dalam koleksi, gunakan Vector(tidak dapat diubah) atau ArrayBuffer(dapat diubah) atau mungkin Array(yang hanya merupakan array Java, kecuali lagi Anda mengindeks ke dalamnya dengan (i)bukan [i]).


1
Pada dasarnya saya mencari sesuatu seperti ArrayList di java. Saya kira kekal juga akan baik-baik saja.
Andriy Drozdyuk

1
ArrayBufferbekerja seperti ArrayList. Vectorberfungsi seperti yang tidak ArrayListdapat diubah - Anda dapat membaca, tetapi Anda tidak dapat menulis tanpa membuat yang baru.
Rex Kerr

Bagaimana dengan subList? Sebagai contoh di java saya melakukan "data.subList (0, index)".
Andriy Drozdyuk

Nevermind, saya mengerti - ini "slice"! Bisakah saya mengonversi ArrayBuffer ke Vektor? Atau adakah tipe yang lebih umum yang dapat saya kembalikan dari metode? Sebagai contoh di Jawa saya akan mengembalikan antarmuka Daftar.
Andriy Drozdyuk

1
Anda dapat mengonversi ArrayBufferke IndexedSeqmenggunakan .toIndexedSeq; IndexedSeqadalah tipe yang lebih umum. (Dalam hal ini, ternyata benar-benar diimplementasikan sebagai a Vector.) IndexedSeqAdalah supertype koleksi yang masuk akal untuk diindeks. Perhatikan juga bahwa Anda dapat melakukannya Vector() ++ myArrayBuffer, yang akan berfungsi untuk hampir semua koleksi (di kedua sisi). ++membangun koleksi baru dari dua yang Anda tentukan, mempertahankan jenis yang di sebelah kiri. Vector()adalah vektor kosong, sehingga akan menghasilkan apa yang Anda inginkan.
Rex Kerr

121

Lebih aman adalah untuk digunakan liftsehingga Anda dapat mengekstraksi nilai jika ada dan gagal jika tidak.

data.lift(2)

Ini akan mengembalikan Tidak Ada jika daftar tidak cukup panjang untuk menyediakan elemen itu, dan Beberapa (nilai) jika ya.

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

Setiap kali Anda melakukan operasi yang mungkin gagal dengan cara ini, sangat bagus untuk menggunakan Opsi dan mendapatkan sistem tipe untuk membantu memastikan Anda menangani kasus di mana elemen tidak ada.

Penjelasan:

Ini berfungsi karena Daftar apply(yang hanya l(index)berupa tanda kurung, misalnya ) seperti fungsi parsial yang didefinisikan di mana pun daftar memiliki elemen. The List.liftMetode ternyata parsial applyfungsi (fungsi yang hanya ditetapkan untuk beberapa masukan) ke dalam fungsi normal (didefinisikan untuk setiap masukan) oleh dasarnya membungkus hasilnya dalam Option.


11
Angkat itu indah. Saya dapat menghindari kesalahan arrayIndexOutOfBound, tanpa memeriksa ukuran array ..
Naveen Sachar

9

Mengapa tanda kurung?

Berikut adalah kutipan dari pemrograman buku di scala .

Gagasan penting lainnya yang diilustrasikan oleh contoh ini akan memberi Anda wawasan tentang mengapa array diakses dengan tanda kurung di Scala. Scala memiliki kasus khusus lebih sedikit daripada Jawa. Array hanyalah contoh kelas seperti kelas lain di Scala. Ketika Anda menerapkan tanda kurung yang mengelilingi satu atau lebih nilai ke suatu variabel, Scala akan mengubah kode menjadi doa metode yang bernama terapkan pada variabel itu. Jadi greetStrings (i) ditransformasikan menjadi greetStrings.apply (i). Jadi mengakses elemen array di Scala hanyalah pemanggilan metode seperti yang lainnya. Prinsip ini tidak terbatas pada array: setiap aplikasi objek ke beberapa argumen dalam tanda kurung akan ditransformasikan menjadi pemanggilan metode yang berlaku. Tentu saja ini akan dikompilasi hanya jika objek jenis itu benar-benar mendefinisikan metode yang berlaku. Jadi ini bukan kasus khusus; itu adalah aturan umum.

Berikut adalah beberapa contoh cara menarik elemen tertentu (elem pertama dalam kasus ini) menggunakan gaya pemrograman fungsional.

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

Ini adalah cara yang disukai untuk mengakses data Daftar melalui indeks saat ini:

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

Tetapi seperti Rex Kerr yang diuraikan di atas: Jika Anda menggunakan indeks, Anda harus mempertimbangkan untuk menggunakan Vektor daripada Daftar.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.