Apa cara tercepat untuk mengubah String menjadi Angka di JavaScript?

122

Nomor berapa pun, itu nomor. String terlihat seperti angka, itu angka. Segala sesuatu yang lain, berjalan NaN.

'a' => NaN
'1' => 1
1 => 1
beatak
sumber
Apa yang tercepat bergantung pada pengoptimalan dalam implementasi tertentu pada waktu tertentu. Tidak ada cara yang secara obyektif "tercepat".
I Hate Lazy
2
Apa yang harus dilakukan dengan '1a'string? Dengan ' 1'satu? Dengan kata lain, mengapa metode paling umum untuk melakukan itu ( Number(x)dan parseInt(x, 10)) tidak cukup bagi Anda?
raina77ow
Tes jsperf sebelumnya: jsperf.com/converting-string-to-int/3
epascarello
di sini perbandingan kinerja yang baik dari metode yang berbeda: jsben.ch/#/NnBKM
EscapeNetscape

Jawaban:

192

Ada 4 cara untuk melakukannya sejauh yang saya tahu.

Number(x);
parseInt(x, 10);
parseFloat(x);
+x;

Dengan tes cepat yang saya buat ini, sebenarnya tergantung pada browser.

http://jsperf.com/best-of-string-to-number-conversion/2

Implicit menandai yang tercepat di 3 browser, tetapi itu membuat kode sulit dibaca ... Jadi, pilih apa pun yang Anda suka!

beatak
sumber
7
Menariknya, Google Analytics (bagian yang Anda sisipkan ke situs web Anda) digunakan 1*untuk konversi tanggal-ke-angka, yang mirip dengan di +atas. yaitu 1*new Date()daripada +new Date(). Mungkin lebih mudah dibaca?
Matthew Wilcoxson
1
Saya rasa 1*lebih disukai karena kurang rawan kesalahan. Variabel menggantung yang tidak diinginkan sebelumnya +1bukanlah kesalahan parsing. Ini adalah trik yang mirip dengan penggunaan if (MYCONSTANT == myvar)dalam C.
Tomas
5
@beatak - Pengoptimalan saat ini tampaknya lebih menyukai metode asli daripada konversi implisit. Saya mendapatkan yang tercepat untuk Number () di Chrome 37.0.2062.124 pada Windows Server 2008 R2 / 7 dan ParseInt () di Firefox 30.0 dengan implisit menjadi yang paling lambat untuk keduanya. Selain itu, Anda dapat mempertimbangkan untuk menyertakan pelampung literal string dalam pengujian untuk perbandingan umum. Dugaan saya adalah bahwa ini dapat mengubah urutan dalam beberapa kasus karena konversi string ke float umumnya lebih lambat daripada konversi string ke int. Cara pengujiannya sekarang, itu lolos dengan konversi string ke int saat Number () digunakan.
Nolo
1
Chrome 61.0.3163. Angka () adalah yang tercepat dari semuanya.
Dmitry Petukhov
70

Setidaknya ada 5 cara untuk melakukan ini:

Jika Anda ingin mengonversi ke bilangan bulat saja, cara cepat (dan pendek) lainnya adalah tidak menggunakan bit -ganda (yaitu menggunakan dua karakter tilde):

misalnya

~~x;

Referensi: http://james.padolsey.com/cool-stuff/double-bitwise-not/

5 cara umum yang saya ketahui sejauh ini untuk mengonversi string menjadi angka semuanya memiliki perbedaan (ada lebih banyak operator bitwise yang berfungsi, tetapi semuanya memberikan hasil yang sama seperti ~~). JSFiddle ini menunjukkan hasil berbeda yang dapat Anda harapkan di konsol debug: http://jsfiddle.net/TrueBlueAussie/j7x0q0e3/22/

var values = ["123",
          undefined,
          "not a number",
          "123.45",
          "1234 error",
          "2147483648",
          "4999999999"
          ];

for (var i = 0; i < values.length; i++){
    var x = values[i];

    console.log(x);
    console.log(" Number(x) = " + Number(x));
    console.log(" parseInt(x, 10) = " + parseInt(x, 10));
    console.log(" parseFloat(x) = " + parseFloat(x));
    console.log(" +x = " + +x);
    console.log(" ~~x = " + ~~x);
}

Konsol debug:

123
  Number(x) = 123
  parseInt(x, 10) = 123
  parseFloat(x) = 123
  +x = 123
  ~~x = 123
undefined
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
null
  Number(x) = 0
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = 0
  ~~x = 0
"not a number"
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
123.45
  Number(x) = 123.45
  parseInt(x, 10) = 123
  parseFloat(x) = 123.45
  +x = 123.45
  ~~x = 123
1234 error
  Number(x) = NaN
  parseInt(x, 10) = 1234
  parseFloat(x) = 1234
  +x = NaN
  ~~x = 0
2147483648
  Number(x) = 2147483648
  parseInt(x, 10) = 2147483648
  parseFloat(x) = 2147483648
  +x = 2147483648
  ~~x = -2147483648
4999999999
  Number(x) = 4999999999
  parseInt(x, 10) = 4999999999
  parseFloat(x) = 4999999999
  +x = 4999999999
  ~~x = 705032703

The ~~xHasil Versi di sejumlah di "lebih" kasus, di mana orang lain sering mengakibatkan undefined, tapi gagal untuk input tidak valid (misalnya itu akan kembali 0jika string berisi karakter non-nomor setelah angka yang benar).

Meluap

Harap dicatat: Integer overflow dan / atau bit truncation dapat terjadi dengan ~~, tetapi tidak dengan konversi lainnya. Meskipun tidak biasa untuk memasukkan nilai sebesar itu, Anda perlu menyadari hal ini. Contoh diperbarui untuk menyertakan nilai yang jauh lebih besar.

Beberapa tes Perf menunjukkan bahwa standar parseIntdan parseFloatfungsi sebenarnya adalah opsi tercepat, mungkin sangat dioptimalkan oleh browser, tetapi semuanya tergantung pada kebutuhan Anda karena semua opsi cukup cepat : http://jsperf.com/best-of-string-to -konversi-angka / 37

Ini semua tergantung pada bagaimana tes kinerja dikonfigurasi karena beberapa menunjukkan parseInt / parseFloat menjadi jauh lebih lambat.

Teori saya adalah:

  • Kebohongan
  • Garis sialan
  • Statistik
  • Hasil JSPerf :)
Hilang Coding
sumber
3
Berhati-hatilah untuk angka yang lebih besar dari 2147483647. mis .: ~~4294967296return 0.
Joseph Goh
@JosephGoh: Ketika saya mendapat kesempatan, saya akan memperluas hasil untuk menyertakan int range overflow. Umumnya, jika angkanya sebesar itu, Anda memiliki antarmuka yang sangat khusus sehingga perlu waspada terhadap overflow. Cheers
Gone Coding
@JosephGoh: Menariknya, di Chrome, Anda tidak mendapatkan 0, Anda mendapatkan angka negatif melebihi nilai maks yang ditandatangani. Kemudian tampaknya hanya menjatuhkan bit ekstra ketika Anda melebihi nilai int max unsigned. misalnya "4999999999" => 705032703
Pergi Coding
8

Awali string dengan +operator.

console.log(+'a') // NaN
console.log(+'1') // 1
console.log(+1) // 1
Pratheep
sumber
7

Cara cepat untuk mengubah string menjadi integer adalah dengan menggunakan bitwise atau, seperti ini:

x | 0

Meskipun itu tergantung pada bagaimana penerapannya, dalam teori itu harus relatif cepat (setidaknya secepat +x) karena pertama-tama akan dilemparkan xke sebuah angka dan kemudian melakukan atau.

pengguna3784814
sumber
Ya, tapi saya yakin teknik ini memotong bilangan bulat besar, itu sangat buruk. Untuk dicatat, saya juga bisa digunakan sebagai pengganti Math.floor (), tetapi dengan masalah yang sama.
Jean
Berikut adalah jsperf dari berbagai operator bitwise dalam hubungannya dengan metode di jawaban pertama. Saya mengacak urutannya karena saya menemukan bahwa beberapa browser akan mengoptimalkan pengujian berikutnya berdasarkan kode serupa dari pengujian sebelumnya. Tidak seperti penjawab teratas, saya menemukan bahwa implisit adalah metode terburuk.
Pluto
4

Berikut adalah cara sederhana untuk melakukannya: var num = Number (str); dalam contoh ini str adalah variabel yang berisi string. Anda dapat menguji dan melihat cara kerjanya buka: Google chrome developer tools , kemudian pergi ke konsol dan paste kode berikut. baca komentar untuk lebih memahami bagaimana konversi dilakukan.

// Here Im creating my variable as a string
var str = "258";


// here im printing the string variable: str
console.log ( str );


// here Im using typeof , this tells me that the variable str is the type: string
console.log ("The variable str is type: " + typeof str);


// here is where the conversion happens
// Number will take the string in the parentesis and transform it to a variable num as type: number
var num = Number(str);
console.log ("The variable num is type: " + typeof num);
Edmundo
sumber
4

Saya merasa itu num * 1sederhana, jelas, dan berfungsi untuk integer dan float ...

Daniel Smith
sumber
3

Ini mungkin tidak secepat itu, tetapi memiliki manfaat tambahan untuk memastikan nomor Anda setidaknya memiliki nilai tertentu (misalnya 0), atau paling banyak nilai tertentu:

Math.max(input, 0);

Jika Anda perlu memastikan nilai minimum, biasanya Anda akan melakukannya

var number = Number(input);
if (number < 0) number = 0;

Math.max(..., 0) menyelamatkan Anda dari menulis dua pernyataan.

Dan Dascalescu
sumber
Mengapa tidak digunakan Math.abs(input)? Ini juga mengubah string menjadi angka positif, dan menyimpan beberapa karakter tambahan.
Aaron Gillion
1
@AaronGillion: Math.max (-5, 0) akan mengembalikan 0; Math.abs (-5) akan mengembalikan 5. Tergantung pada use case yang lebih masuk akal.
Dan Dascalescu
1
Oh, ups, ya, kasus penggunaan saya jauh berbeda selama larut malam saya menulis komentar itu.
Aaron Gillion
Jika inputtidak dapat dikonversi ke nomor Anda akan mendapatkanNaN
Domas
0

Anda dapat mencoba menggunakan UnitOf , pustaka konversi pengukuran dan tipe data yang baru saja kami rilis secara resmi! UnitOf sangat cepat, berukuran kecil, dan efisien dalam mengonversi semua tipe data tanpa pernah menimbulkan kesalahan atau null / undefined. Nilai default yang Anda tentukan atau default UnitOf dikembalikan saat konversi tidak berhasil.

//One liner examples
UnitOf.DataType("12.5").toFloat(); //12.5 of type Float is returned. 0 would be returned if conversion failed.
UnitOf.DataType("Not A Num").toInt(10); //10 of type Int is returned as the conversion failed.

//Or as a variable
var unit = UnitOf.DataType("12.5");
unit.toInt(5); //12.5 of type Float is returned. 5 would be returned if the conversion failed.
unit.toFloat(8); // 12 of type Int is returned. 8 would be returned if the conversion failed.
Digidemik
sumber
0

Cara tercepat adalah menggunakan -0:

const num = "12.34" - 0;
Arturas
sumber