Saya senang seseorang tidak takut untuk menanyakan beberapa pertanyaan mendasar.
octopusgrabbus
4
+1 - bagian dari tantangannya adalah bahwa dokumen Clojure terkadang tidak menjawab pertanyaan "dasar" yang kami anggap remeh dalam bahasa lain. (Saya memiliki pertanyaan yang sama 3 tahun kemudian dan menemukan ini).
Glenn
3
@octopusgrabbus - Saya akan tertarik untuk mengetahui "mengapa" orang takut mengajukan pertanyaan mendasar?
appshare.co
1
@ Zubair seharusnya hal-hal dasar sudah dijelaskan di suatu tempat sehingga Anda kemungkinan besar mengabaikan sesuatu dan pertanyaan Anda akan diturunkan karena "tidak ada upaya penelitian".
Al.G.
1
Bagi mereka yang datang ke sini dari Google mencari untuk mengkonversi "9"ke 9, ini adalah hal terbaik yang bekerja untuk saya: (Integer. "9").
weltschmerz
Jawaban:
79
Ini akan bekerja pada 10pxataupx10
(defn parse-int [s](Integer. (re-find #"\d+" s )))
Jawaban bagus! Ini lebih baik daripada menggunakan read-string menurut saya. Saya mengubah jawaban saya untuk menggunakan teknik Anda. Saya membuat beberapa perubahan kecil juga.
Benjamin Atkin
ini memberi sayaException in thread "main" java.lang.ClassNotFoundException: Integer.,
maazza
83
Jawaban baru
Saya lebih suka jawaban snrobot. Menggunakan metode Java lebih sederhana dan lebih kuat daripada menggunakan read-string untuk kasus penggunaan sederhana ini. Saya memang membuat beberapa perubahan kecil. Karena penulis tidak mengesampingkan angka negatif, saya menyesuaikannya untuk memungkinkan angka negatif. Saya juga membuatnya sehingga membutuhkan nomor untuk memulai di awal string.
Saya paling suka jawaban Anda - sayang sekali ini tidak disediakan oleh perpustakaan inti clojure. Satu kritik kecil - secara teknis Anda ifharus menjadi whenkarena tidak ada lagi blok di fns Anda.
quux00
1
Ya, tolong jangan berhenti membaca setelah cuplikan kode pertama atau kedua!
Benjamin Atkin
2
Angka-angka di depan dengan angka nol di depan. read-stringmenafsirkannya sebagai oktal: (read-string "08")melempar pengecualian. Integer/valueOfmemperlakukannya sebagai desimal: (Integer/valueOf "08")dievaluasi menjadi 8.
rubasov
Perhatikan juga bahwa read-stringmelempar pengecualian jika Anda memberinya string kosong atau sesuatu seperti "29px"
Ilya Boyandin
Seperti seharusnya. Saya menjawab pertanyaan dalam judul, dan apa yang orang harapkan ketika mereka melihat halaman ini, sebelum saya menjawab pertanyaan di badan pertanyaan. Ini cuplikan kode terakhir di badan jawaban saya.
Terima kasih. Ini sangat membantu dalam membagi produk menjadi beberapa urutan angka.
octopusgrabbus
3
Karena kita berada di tanah Jawa untuk jawaban ini, umumnya disarankan untuk digunakan Integer/valueOf, daripada konstruktor Integer. Kelas Integer menyimpan nilai antara -128 dan 127 untuk meminimalkan pembuatan objek. Integer Javadoc menjelaskan ini seperti halnya posting ini: stackoverflow.com/a/2974852/871012
quux00
15
Ini bekerja sebagai gantinya bagi saya, jauh lebih lurus ke depan.
ini bagus untuk input tepercaya, seperti misalnya teka-teki pemrograman. @ jerney benar: hati-hati untuk tidak menggunakannya dalam kode aktual.
hraban
10
AFAIK tidak ada solusi standar untuk masalah Anda. Saya pikir sesuatu seperti yang berikut ini, yang menggunakan clojure.contrib.str-utils2/replace, akan membantu:
Tidak direkomendasikan. Ini akan berfungsi sampai seseorang melemparnya 1.5... dan itu juga tidak menggunakan clojure.string/replacefungsi bawaan.
tar
8
Ini tidak sempurna, tapi ada sesuatu dengan filter, Character/isDigitdan Integer/parseInt. Ini tidak akan berfungsi untuk angka floating point dan gagal jika tidak ada digit di input, jadi Anda mungkin harus membersihkannya. Saya harap ada cara yang lebih baik untuk melakukan ini yang tidak melibatkan begitu banyak Jawa.
Pertanyaannya adalah tentang mengurai string menjadi angka.
(number? 0.5);;=> true
Jadi dari desimal di atas harus diurai juga.
Mungkin tidak tepat menjawab pertanyaan sekarang, tetapi untuk penggunaan umum saya pikir Anda ingin menjadi ketat tentang apakah itu angka atau tidak (jadi "px" tidak diizinkan) dan biarkan penelepon menangani non-angka dengan mengembalikan nihil:
Untuk orang lain yang ingin mengurai String literal yang lebih normal menjadi angka, yaitu string yang tidak memiliki karakter non numerik lainnya. Ini adalah dua pendekatan terbaik:
Tidak seperti menggunakan read-stringdari clojure.coreyang tidak aman untuk digunakan pada input yang tidak dipercaya, edn/read-stringaman untuk dijalankan pada input yang tidak dipercaya seperti input pengguna.
Ini seringkali lebih nyaman daripada interop Java jika Anda tidak perlu memiliki kontrol khusus dari jenisnya. Itu dapat menguraikan sejumlah literal yang dapat diurai Clojure seperti:
Juga, hanya pertanyaan yang aneh: mengapa Anda menggunakan (t/refer-tupelo)alih-alih membuat pengguna melakukannya (:require [tupelo.core :refer :all])?
Qwerp-Derp
refer-tupelodimodelkan setelah refer-clojure, dalam hal itu tidak termasuk segala cara (:require [tupelo.core :refer :all]).
"9"
ke9
, ini adalah hal terbaik yang bekerja untuk saya:(Integer. "9")
.Jawaban:
Ini akan bekerja pada
10px
ataupx10
itu hanya akan menguraikan digit kontinu pertama
sumber
Exception in thread "main" java.lang.ClassNotFoundException: Integer.,
Jawaban baru
Saya lebih suka jawaban snrobot. Menggunakan metode Java lebih sederhana dan lebih kuat daripada menggunakan read-string untuk kasus penggunaan sederhana ini. Saya memang membuat beberapa perubahan kecil. Karena penulis tidak mengesampingkan angka negatif, saya menyesuaikannya untuk memungkinkan angka negatif. Saya juga membuatnya sehingga membutuhkan nomor untuk memulai di awal string.
Selain itu saya menemukan bahwa Integer / parseInt mem-parsing sebagai desimal ketika tidak ada radix yang diberikan, bahkan jika ada nol di depannya.
Jawaban lama
Pertama, untuk mengurai hanya integer (karena ini adalah hit di google dan itu informasi latar belakang yang bagus):
Anda dapat menggunakan pembaca :
Anda dapat memeriksa apakah itu nomor setelah dibaca:
Saya tidak yakin apakah input pengguna dapat dipercaya oleh pembaca clojure sehingga Anda dapat memeriksa sebelum membacanya juga:
Saya pikir saya lebih suka solusi terakhir.
Dan sekarang, untuk pertanyaan spesifik Anda. Untuk mem-parsing sesuatu yang dimulai dengan integer, seperti
29px
:sumber
if
harus menjadiwhen
karena tidak ada lagi blok di fns Anda.read-string
menafsirkannya sebagai oktal:(read-string "08")
melempar pengecualian.Integer/valueOf
memperlakukannya sebagai desimal:(Integer/valueOf "08")
dievaluasi menjadi 8.read-string
melempar pengecualian jika Anda memberinya string kosong atau sesuatu seperti "29px"sumber
Integer/valueOf
, daripada konstruktor Integer. Kelas Integer menyimpan nilai antara -128 dan 127 untuk meminimalkan pembuatan objek. Integer Javadoc menjelaskan ini seperti halnya posting ini: stackoverflow.com/a/2974852/871012Ini bekerja sebagai gantinya bagi saya, jauh lebih lurus ke depan.
(baca-string "123")
=> 123
sumber
read-string
dapat mengeksekusi kode per dokumen: clojuredocs.org/clojure.core/read-stringAFAIK tidak ada solusi standar untuk masalah Anda. Saya pikir sesuatu seperti yang berikut ini, yang menggunakan
clojure.contrib.str-utils2/replace
, akan membantu:sumber
1.5
... dan itu juga tidak menggunakanclojure.string/replace
fungsi bawaan.Ini tidak sempurna, tapi ada sesuatu dengan
filter
,Character/isDigit
danInteger/parseInt
. Ini tidak akan berfungsi untuk angka floating point dan gagal jika tidak ada digit di input, jadi Anda mungkin harus membersihkannya. Saya harap ada cara yang lebih baik untuk melakukan ini yang tidak melibatkan begitu banyak Jawa.sumber
Saya mungkin akan menambahkan beberapa hal ke persyaratan:
Mungkin sesuatu seperti:
dan mungkin poin bonus untuk menjadikan ini metode multi yang memungkinkan untuk bawaan yang disediakan pengguna selain 0.
sumber
Memperluas jawaban snrobot:
Versi ini mengembalikan nihil jika tidak ada digit di input, daripada meningkatkan pengecualian.
Pertanyaan saya adalah apakah boleh menyingkat nama menjadi "str-> int", atau apakah hal-hal seperti ini harus selalu ditentukan secara penuh.
sumber
Juga menggunakan
(re-seq)
fungsi dapat memperluas nilai kembali ke string yang berisi semua angka yang ada di string input agar:(defn convert-to-int [s] (->> (re-seq #"\d" s) (apply str) (Integer.)))
(convert-to-int "10not123")
=>10123
(type *1)
=>java.lang.Integer
sumber
Pertanyaannya adalah tentang mengurai string menjadi angka.
Jadi dari desimal di atas harus diurai juga.
Mungkin tidak tepat menjawab pertanyaan sekarang, tetapi untuk penggunaan umum saya pikir Anda ingin menjadi ketat tentang apakah itu angka atau tidak (jadi "px" tidak diizinkan) dan biarkan penelepon menangani non-angka dengan mengembalikan nihil:
Dan jika Floats bermasalah untuk domain Anda, bukan
Float/parseFloat
putbigdec
atau sesuatu yang lain.sumber
Untuk orang lain yang ingin mengurai String literal yang lebih normal menjadi angka, yaitu string yang tidak memiliki karakter non numerik lainnya. Ini adalah dua pendekatan terbaik:
Menggunakan Java interop:
Ini memungkinkan Anda mengontrol dengan tepat jenis yang ingin Anda parsing nomornya, ketika itu penting untuk use case Anda.
Menggunakan pembaca Clojure EDN:
Tidak seperti menggunakan
read-string
dariclojure.core
yang tidak aman untuk digunakan pada input yang tidak dipercaya,edn/read-string
aman untuk dijalankan pada input yang tidak dipercaya seperti input pengguna.Ini seringkali lebih nyaman daripada interop Java jika Anda tidak perlu memiliki kontrol khusus dari jenisnya. Itu dapat menguraikan sejumlah literal yang dapat diurai Clojure seperti:
Daftar lengkap di sini: https://www.rubberducking.com/2019/05/clojure-for-non-clojure-programmers.html#numbers
sumber
Untuk kasus sederhana, Anda bisa menggunakan regex untuk menarik string digit pertama seperti yang disebutkan di atas.
Jika Anda memiliki situasi yang lebih rumit, Anda mungkin ingin menggunakan perpustakaan InstaParse:
sumber
(t/refer-tupelo)
alih-alih membuat pengguna melakukannya(:require [tupelo.core :refer :all])
?refer-tupelo
dimodelkan setelahrefer-clojure
, dalam hal itu tidak termasuk segala cara(:require [tupelo.core :refer :all])
.