2015-09-01 13 views
20

Đã phát xung quanh với một số mã để tạo một mảng số 0 và nhận thấy rằng chỉ có một giá trị NaN được trả lại thay vì 0. Tôi nhận được điều này trong Chrome, Node và Firefox.Nhận NaN không đồng nhất ánh xạ parseInt

Điều gì gây ra giá trị thứ hai là NaN?

var arr = new Array(32).join(0).split('').map(parseInt) 
// prints [0, NaN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
console.dir(arr) 
+3

Bạn đã thử 'mảng mới (32) .fill (0);'? –

+1

Bạn có thể quan tâm [Cách hiệu quả nhất để tạo một mảng JavaScript không đầy?] (Http://stackoverflow.com/q/1295584/1529630) – Oriol

Trả lời

27

đó là bởi vì các hàm được chuyển vào map sẽ được gọi với ba đối số:

  1. Mảng mục hiện
  2. Chỉ số của mục đó
  3. Toàn bộ mảng

Trong trường hợp này, chức năng đó là parseInt, mà chỉ sử dụng hai đối số:

  1. Chuỗi được phân tích cú pháp
  2. Cơ số được sử dụng để phân tích cú pháp e chuỗi
  3. Đối số bổ sung sẽ bị bỏ qua.

Do đó, đối với mục thứ 2 trong mảng (tức làindex 1), cuộc gọi sẽ được

parseInt("0", 1, ignoredArray) 

Khi radix là 1, NaN được trả về:

  • Hãy R = ToInt32 (radix).
  • Nếu R ≠ 0, sau đó
    • Nếu R < 2 hoặc R> 36 tuổi, sau đó trở về NaN.

Cũng lưu ý rằng nếu bạn sử dụng một số lớn hơn như new Array(99), mà bạn sẽ thấy NaN s bắt đầu từ chỉ số 37.

+0

Và 0 là một cơ số hợp lệ? – immibis

+0

Đã có một nhu cầu thực tế để phân tích một chuỗi các chuỗi số nguyên, giải pháp đơn giản nhất là sử dụng 'parseFloat', chỉ lấy một đối số. – Mihai

+0

@immibis Về mặt toán học, một cơ số 0 không có ý nghĩa gì cả. Vì vậy, nếu bạn sử dụng 0, JS sẽ giả sử bạn có nghĩa là 10. – Oriol

9

Chức năng .map() đi ba đối số để gọi lại trong đó hai được sử dụng bởi parseInt(): giá trị, và chỉ số (thứ ba là mảng chính nó). Khi chỉ mục là 1, mọi chuỗi chữ số sẽ là một giá trị không hợp lệ. Hàm parseInt() bỏ qua đối số thứ hai khi nó là 0.

Xây dựng: đối với phần tử đầu tiên, parseInt() được gọi là như thế này:

parseInt("0", 0) 

vì giá trị mảng là zero và chỉ số là zero. Trong lần gọi thứ hai, đó là:

parseInt("0", 1) 

và trả lại NaN.

Lưu ý rằng nếu bạn không quá cầu kỳ về kết quả là tất cả các số nguyên, bạn có thể làm những gì bạn đang cố gắng để làm với Số constructor:

var arr = new Array(32).join(0).split('').map(Number); 

Trong ES2015 (tiêu chuẩn phê chuẩn mới nhất cho JavaScript, mà nếu chúng ta tất cả đều rất tốt sẽ được thực hiện đầy đủ trong tất cả các trình duyệt như món quà Giáng sinh của chúng tôi), bạn có thể sử dụng .fill() chức năng:

var arr = new Array(31).fill(0); 
+6

[** Ba ** đối số] (https: // nhà phát triển. mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map), thứ ba là mảng mà bạn đang lập bản đồ. 'parseInt' bỏ qua phần thứ ba. – user2357112

+0

@ user2357112 đúng vậy, và có 'parseInt' chỉ xem xét hai đối số đầu tiên của nó. – Pointy

6

Việc lập bản đồ đi ba đối số cho chức năng của nó:

  • phần tử;
  • chỉ mục của phần tử đó trong mảng; và
  • chính mảng đó.

Chức năng parseInt sẽ xem xét hai trong số đầu tiên, xử lý đầu tiên chính xác như chuỗi nhưng xử lý thứ hai làm cơ sở để sử dụng. Khi cơ sở không phải là số không cũng như trong phạm vi bao gồm 2..36, giá trị trả về là NaN(1). Nếu bạn đã có một mảng với các yếu tố bốn mươi, bạn cũng sẽ thấy một loạt các NaN giá trị ở cuối:

0, NaN, 0, 0, 0, ... 0, 0, 0, NaN, NaN 

Bạn cũng sẽ nhận được một số kết quả khá lạ nếu chuỗi số là bất cứ điều gì khác hơn không, vì chỉ số mảng sẽ quyết định căn cứ nào được sử dụng để diễn giải nó.

Để thực sự sửa chữa này, bạn có thể chỉ cung cấp một chức năng mà sẽ dịch những gì mapmang đến cho bạn những gì parseInthy vọng (bản đồ bản đồ, tôi đoán bạn có thể gọi nó):

function myParseInt(s,r,a) { return parseInt(s,10); } 
var arr = new Array(32).join(0).split('').map(myParseInt) 
alert(arr) 

Bạn cũng có thể muốn xem cách tạo mảng này, nó sẽ thực sự kết thúc dưới dạng mảng có kích thước 31 thay vì 32. Nếu bạn chỉ muốn một mảng gồm '0' ký tự, bạn có thể sử dụng:

var arr = new Array(32).fill('0') 

giả sử bạn có trình duyệt hỗ trợ ECMAScript 2015, là Safari, Firefox và Chrome-máy tính để bàn kể từ thời điểm câu trả lời này.


(1) Một cơ sở của không phải là trường hợp mặc định để xử lý những thứ như tiền tố hex.

Một cơ sở không có ý nghĩa trong hệ thống vị trí thuần túy (trong đó mỗi chữ số được nhân với lũy thừa của cơ sở và tích lũy) vì chữ số được phép duy nhất sẽ là 0, vì vậy mỗi giá trị địa điểm sẽ không được nhân lên bởi 1n. Nói cách khác, số duy nhất có thể trong một hệ thống cơ sở một sẽ bằng không.

Căn cứ từ 2 đến 36 do đó hợp lý hơn.

+0

Bạn nói cơ số 1 là không khả thi vì số duy nhất sẽ là '1^n', trong cơ sở thực tế 1 có nhiều chữ số như số (tức là' 30' = '1 ....... 1' ba mươi lần). Các thao tác trên các số cơ sở 1 rất dài, đặc biệt là in số cơ sở 1 có thể yêu cầu in một số lượng rất lớn số không phải là thông tin rất nhiều. Tất nhiên đây là quy ước và cũng có định lý yêu cầu cơ sở 1 được chứng minh (tức là 3 máy đăng ký hoàn chỉnh) – GameDeveloper

+1

@DarioOO, base 1 chỉ có chữ số '0' (không phải' 1'), giống như base 2 chỉ có '0' và' 1'. Trong một hệ thống hoàn toàn vị trí, rằng '0' có thể * chỉ * bao giờ tạo ra không vì giá trị từ một vị trí đã cho' n' sẽ là '0 x 1^n'. Nói cách khác, '00000 ... 000' là số không, không có vấn đề gì * làm thế nào * nhiều chữ số bạn có. Cơ sở 1 có thể khả thi cho một hệ thống không có vị trí tuy nhiên vì vậy tôi sẽ làm rõ nó là ý của tôi. – paxdiablo

+0

Đó là vì bạn mở rộng một định nghĩa phù hợp với số base2 +, nó thường là một số được làm bằng 1s không bằng 0: https://en.wikipedia.org/wiki/Unary_numeral_system Nó không phải là định nghĩa duy nhất cho một cơ sở một số, có tồn tại các định nghĩa chung có cơ sở không chủ đạo của các định nghĩa. – GameDeveloper

Các vấn đề liên quan