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.

Masiar
sumber

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

Landei
sumber
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)
agilesteel
sumber
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)
Markus Weninger
sumber
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)
Venkat
sumber
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
Ramesh Muthavarapu
sumber
1
Ya, kita bisa, tetapi itu akan menjadi ide yang buruk untuk semua alasan yang disebutkan dalam jawaban lain.
jwvh