Menambahkan elemen ke akhir daftar di Scala


223

Kedengarannya seperti pertanyaan bodoh, tetapi yang saya temukan di internet hanyalah sampah. Saya tidak bisa menambahkan elemen tipe Tke dalam daftar List[T]. Saya mencoba myList ::= myElementtetapi tampaknya itu menciptakan objek aneh dan mengakses untuk myList.lastselalu mengembalikan elemen pertama yang dimasukkan ke dalam daftar.

Jawaban:


394
List(1,2,3) :+ 4

Results in List[Int] = List(1, 2, 3, 4)

Perhatikan bahwa operasi ini memiliki kompleksitas O (n). Jika Anda perlu operasi ini sering, atau untuk daftar panjang, pertimbangkan untuk menggunakan tipe data lain (misalnya ListBuffer).


7
Tidak ada O (2 * n), faktor konstan diabaikan untuk kompleksitas asimptotik. Saya pikir Listdikonversi menjadi ListBuffer, elemen ditambahkan, dan ListBufferkembali dikonversi (seperti Stringdan StringBuilderdi Jawa), tapi itu hanya dugaan.
Landei

2
Ini adalah O (n) karena Anda harus melintasi daftar seluruhnya untuk mencapai pointer elemen terakhir dan dapat menambahkan elemen yang membuat pointer elemen terakhir menunjuk ke sana.
pisaruk

39
@pisaruk jika itu yang terjadi, orang hanya bisa mempertahankan pointer ke kepala dan ekor. Namun, daftar di scala tidak dapat diubah, yang berarti bahwa untuk "memodifikasi" elemen terakhir dari daftar, seseorang perlu membuat salinannya terlebih dahulu. Salinannya adalah O (n) - bukan traversal dari daftar itu sendiri.

2
Saya percaya itu O (n) hanya karena membuat daftar baru
Raffaele Rossi

3
Operator kontra memiliki kompleksitas O (1), karena bekerja pada sisi "yang dimaksudkan" dari daftar.
Landei

67

Itu karena Anda seharusnya tidak melakukannya (setidaknya dengan daftar yang tidak berubah). Jika Anda benar-benar perlu menambahkan elemen pada akhir struktur data dan struktur data ini benar-benar harus menjadi daftar dan daftar ini benar-benar harus tidak berubah kemudian lakukan hal berikut:

(4 :: List(1,2,3).reverse).reverse

atau itu:

List(1,2,3) ::: List(4)

Terima kasih banyak! Itulah tepatnya yang saya cari. Saya kira dari jawaban Anda, saya seharusnya tidak melakukan itu ... Saya akan merevisi struktur saya dan melihat apa yang bisa saya lakukan. Terima kasih lagi.
Masiar

6
@Masiar menggunakan Vector jika Anda ingin menambahkan immutability dan efisien. Lihat bagian karakteristik kinerja di scala-lang.org/docu/files/collections-api/collections.html
Arjan Blokzijl

29
"Buat daftar dengan menambahkan dan kemudian membalikkannya" adalah pola yang berguna jika Anda memiliki banyak elemen untuk ditambahkan, tapi saya pikir itu bukan ide yang baik untuk menerapkannya seperti yang Anda lakukan jika menambahkan satu elemen ke sebuah daftar yang ada. Trik "membalikkan ganda" membangun kembali daftar dua kali, sementara :+, tidak efisien karena mungkin, hanya membangun kembali daftar sekali.
Nicolas Payette

25

Daftar dalam Scala tidak dirancang untuk dimodifikasi. Bahkan, Anda tidak bisa menambahkan elemen ke Scala List; itu adalah struktur data yang tidak berubah , seperti Java String. Apa yang sebenarnya Anda lakukan ketika "menambahkan elemen ke daftar" di Scala adalah membuat Daftar baru dari Daftar yang ada . (Sumber)

Alih-alih menggunakan daftar untuk kasus penggunaan seperti itu, saya sarankan untuk menggunakan ArrayBufferatauListBuffer . Struktur data tersebut dirancang untuk menambahkan elemen baru.

Akhirnya, setelah semua operasi Anda selesai, buffer kemudian dapat dikonversi menjadi daftar. Lihat contoh REPL berikut:

scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

scala> var fruits = new ListBuffer[String]()
fruits: scala.collection.mutable.ListBuffer[String] = ListBuffer()

scala> fruits += "Apple"
res0: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple)

scala> fruits += "Banana"
res1: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana)

scala> fruits += "Orange"
res2: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana, Orange)

scala> val fruitsList = fruits.toList
fruitsList: List[String] = List(Apple, Banana, Orange)

3

Ini mirip dengan salah satu jawaban tetapi dengan cara yang berbeda:

scala> val x=List(1,2,3)
x: List[Int] = List(1, 2, 3)

scala> val y=x:::4::Nil
y: List[Int] = List(1, 2, 3, 4)

2

Kami dapat menambahkan atau menambahkan dua daftar atau daftar & larik
Menambahkan:

var l = List(1,2,3)    
l=l:+4 
Result : 1 2 3 4  
var ar = Array(4,5,6)    
for(x<-ar)    
{ l=l:+x}  
  l.foreach(println)

Result:1 2 3 4 5 6

Berlanjut:

var l = List[Int]()  
   for(x<-ar)  
    { l=x::l } //prepending    
     l.foreach(println)   

Result:6 5 4 1 2 3

1
Ya, kita bisa, tetapi itu akan menjadi ide yang buruk untuk semua alasan yang disebutkan dalam jawaban lain.
jwvh
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.