Split pada string kosong mengembalikan larik berukuran 1:
scala> "".split(',')
res1: Array[String] = Array("")
Pertimbangkan bahwa ini mengembalikan array kosong:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Tolong jelaskan :)
Split pada string kosong mengembalikan larik berukuran 1:
scala> "".split(',')
res1: Array[String] = Array("")
Pertimbangkan bahwa ini mengembalikan array kosong:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Tolong jelaskan :)
Jawaban:
Untuk alasan yang sama itu
",test" split ','
dan
",test," split ','
akan mengembalikan larik berukuran 2. Segala sesuatu sebelum pertandingan pertama dikembalikan sebagai elemen pertama.
"".split("wtf").length
menghasilkan 0. Hanya di JS 1.: /
"," split ","
mengembalikan array 0?
Jika Anda membagi jeruk nol kali, Anda mendapatkan tepat satu bagian - jeruk.
"orange".split(',')
, tetapi tidak jelas relevan untuk memisahkan string kosong. Jika saya membagi kekurangan jeruk saya nol kali, saya masih tidak memiliki jeruk; apakah kita menyatakan itu sebagai daftar kosong tanpa jeruk, daftar persis satu tidak ada jeruk, daftar dua belas tidak ada jeruk, atau apa? Ini bukan pertanyaan tentang apa yang akan kita dapatkan, tapi bagaimana kita mewakilinya.
Metode pemisahan Java dan Scala beroperasi dalam dua langkah seperti ini:
",,,".split(",")
mengembalikan array kosong.Menurut ini, hasil dari "".split(",")
harus berupa larik kosong karena langkah kedua, bukan?
Itu harus. Sayangnya, ini adalah casing sudut yang diperkenalkan secara artifisial. Dan yang buruk, tapi setidaknya itu didokumentasikan dalam java.util.regex.Pattern
, jika Anda ingat untuk melihat dokumentasi:
Untuk n == 0, hasilnya adalah untuk n <0, kecuali string kosong tidak akan dikembalikan. (Perhatikan bahwa kasus di mana masukan itu sendiri adalah string kosong yang khusus, seperti dijelaskan di atas, dan parameter batas tidak berlaku di sana.)
Jadi, saya menyarankan Anda untuk selalu lulus n == -1
sebagai parameter kedua (ini akan melewatkan langkah kedua di atas), kecuali Anda secara khusus tahu apa yang ingin Anda capai / Anda yakin bahwa string kosong bukanlah sesuatu yang akan didapat program Anda sebagai input.
Jika Anda sudah menggunakan Guava dalam proyek Anda, Anda dapat mencoba kelas Splitter (dokumentasi) . Ini memiliki API yang sangat kaya, dan membuat kode Anda sangat mudah dipahami.
Splitter.on(".").split(".a.b.c.") // "", "a", "b", "c", ""
Splitter.on(",").omitEmptyStrings().split("a,,b,,c") // "a", "b", "c"
Splitter.on(CharMatcher.anyOf(",.")).split("a,b.c") // "a", "b", "c"
Splitter.onPattern("=>?").split("a=b=>c") // "a", "b", "c"
Splitter.on(",").limit(2).split("a,b,c") // "a", "b,c"
"".split (",", n)
menghasilkan satu elemen array untuk n di (-1, 0, 1) dengan Oracle JDK 8. Akan menyenangkan untuk mendapatkan daftar token yang tidak kosong saja - tebak regex lengkap mungkin diperlukan (seperti "[^,\\s]+[^,]*[^,\\s]*"
).
Memisahkan string kosong mengembalikan string kosong sebagai elemen pertama. Jika tidak ada pembatas yang ditemukan dalam string target, Anda akan mendapatkan array berukuran 1 yang menahan string asli, meskipun kosong.
",".split(",")
mengembalikan array kosong.
Dalam semua bahasa pemrograman, saya tahu string kosong masih merupakan String yang valid. Jadi melakukan pemisahan menggunakan pemisah apa pun akan selalu mengembalikan larik elemen tunggal di mana elemen itu adalah String kosong. Jika itu adalah String null (tidak kosong) maka itu akan menjadi masalah yang berbeda.
Ini split
perilaku diwariskan dari Jawa, untuk lebih baik atau lebih buruk ...
Scala tidak mengesampingkan definisi dari String
primitif.
Catatan, Anda bisa menggunakan limit
argumen untuk mengubah perilaku :
Parameter batas mengontrol berapa kali pola diterapkan dan karenanya memengaruhi panjang larik yang dihasilkan. Jika batas n lebih besar dari nol maka pola akan diterapkan paling banyak n - 1 kali, panjang larik tidak akan lebih dari n, dan entri terakhir larik akan berisi semua masukan di luar pembatas yang cocok terakhir. Jika n non-positif maka pola akan diterapkan sebanyak mungkin dan array dapat memiliki panjang berapa pun. Jika n adalah nol maka pola akan diterapkan sebanyak mungkin, array dapat memiliki panjang berapa pun, dan string kosong yang tertinggal akan dibuang.
yaitu Anda dapat menyetel limit=-1
untuk mendapatkan perilaku (semua?) bahasa lain:
@ ",a,,b,,".split(",")
res1: Array[String] = Array("", "a", "", "b")
@ ",a,,b,,".split(",", -1) // limit=-1
res2: Array[String] = Array("", "a", "", "b", "", "")
Tampaknya terkenal bahwa perilaku Java cukup membingungkan tetapi:
Perilaku di atas dapat diamati setidaknya dari Java 5 hingga Java 8.
Ada upaya untuk mengubah perilaku untuk mengembalikan larik kosong saat memisahkan string kosong di JDK-6559590 . Namun, itu segera dikembalikan ke JDK-8028321 ketika menyebabkan regresi di berbagai tempat. Perubahan tidak pernah membuatnya menjadi rilis awal Java 8.
Catatan: Metode pemisahan tidak ada di Java sejak awal ( bukan di 1.0.2 ) tetapi sebenarnya ada setidaknya dari 1.4 (mis. Lihat JSR51 sekitar tahun 2002). Saya masih menyelidiki ...
Apa yang tidak jelas adalah mengapa Java memilih ini di tempat pertama (kecurigaan saya adalah bahwa ini pada awalnya merupakan kekeliruan / bug dalam "kasus tepi"), tetapi sekarang dimasukkan ke dalam bahasa yang tidak dapat ditarik kembali dan tetap demikian .
"".split(",")
masih mengembalikan array elemen tunggal seperti [""]
.
String kosong tidak memiliki status khusus saat memisahkan string. Anda dapat menggunakan:
Some(str)
.filter(_ != "")
.map(_.split(","))
.getOrElse(Array())