Bạn có thể sử dụng dấu phẩy trong đối tượng JSON không?


392

Khi tạo thủ công một đối tượng hoặc mảng JSON, việc để lại dấu phẩy trên mục cuối cùng trong đối tượng hoặc mảng thường dễ dàng hơn. Ví dụ: mã để xuất ra từ một chuỗi các chuỗi có thể trông giống như (trong C ++ giống như mã giả):

s.append("[");
for (i = 0; i < 5; ++i) {
    s.appendF("\"%d\",", i);
}
s.append("]");

cho bạn một chuỗi như

[0,1,2,3,4,5,]

Điều này có được phép không?


66
Đó là một cái gì đó tôi cần để tìm kiếm trên web một vài ngày trước. Tôi đã không thấy câu trả lời ở đây trên SO, vì vậy, theo nhiệm vụ của trang web, tôi đã đặt ra câu hỏi và trả lời nó để những người khác có thể tìm thấy nó. Đây là điều mà Jeff nói rõ ràng anh ấy muốn thực hiện ở đây.
Ben Combee

5
Như Jeff đã nói, tôi nghĩ việc sử dụng SO như một 'cuốn sổ' những thứ mà bạn phải dành thời gian để tìm kiếm là điều hoàn toàn tốt. Chắc chắn, đây là kết thúc đơn giản của các loại mặt hàng đó, nhưng tôi vẫn nghĩ rằng nó phù hợp, đặc biệt là vì các công cụ javascript khác nhau sẽ giải quyết vấn đề này khác nhau.
pkaeding

6
Tôi cũng đã tự hỏi điều này, vì vậy đó là một câu hỏi hoàn toàn hợp lý.
hoju

48
Đối với tất cả những người chó cái mà ai đó hỏi một câu hỏi đơn giản, xin vui lòng lùi lại. Đây là một trong những lượt truy cập đầu tiên trên google và nó giúp tôi tham khảo câu trả lời nhanh chóng. Cảm ơn OP.

40
Thật thú vị (hoặc kinh khủng) trong IE 8 Tôi vừa tìm thấy alert([1, 2, 3, ].length)sẽ hiển thị "4".
Daniel Earwicker

Câu trả lời:


250

Thật không may , đặc tả JSON không cho phép dấu phẩy. Có một vài trình duyệt sẽ cho phép nó, nhưng nhìn chung bạn cần phải lo lắng về tất cả các trình duyệt.

Nói chung, tôi cố gắng giải quyết vấn đề và thêm dấu phẩy trước giá trị thực, để bạn kết thúc với mã trông như thế này:

s.append("[");
for (i = 0; i < 5; ++i) {
  if (i) s.append(","); // add the comma only if this isn't the first entry
  s.appendF("\"%d\"", i);
}
s.append("]");

Thêm một dòng mã trong vòng lặp for của bạn hầu như không tốn kém ...

Một cách khác tôi đã sử dụng khi xuất cấu trúc thành JSON từ một từ điển của một số dạng là luôn luôn thêm dấu phẩy sau mỗi mục (như bạn đang làm ở trên) và sau đó thêm một mục giả ở cuối không có dấu phẩy (nhưng đó chỉ là lười biếng; ->).

Không hoạt động tốt với một mảng không may.


2
Tôi đã bắt đầu sử dụng định dạng này trong tất cả mã JS của mình (dấu phẩy trước mục trên cùng một dòng) vì lý do chính xác này. Làm cho dấu phẩy thêm dễ dàng hơn nhiều để phát hiện và tiết kiệm rất nhiều thời gian. Thật khó chịu, tôi ước có một tùy chọn để khắc phục lỗi này với firefox (vì điều đó sẽ giúp gỡ lỗi).
lửa

47
Thật đáng tiếc khi ECMA5 chỉ định các dấu vết, nhưng JSON thì không.
FlavorScape

4
Vâng, dòng bổ sung đó hầu như không tốn kém, nhưng vẫn gây phiền toái.
René Nyffalanger

2
Cách tiếp cận này hoạt động cho các vòng lặp được lập chỉ mục. Làm thế nào về ... trong các vòng lặp phong cách? Có một cách thanh lịch?
kgf3JfUtW

2
Thêm một dòng mã có thể phức tạp khi xử lý các thuộc tính. Bạn có thể thấy mình có hàng tấn ifs chỉ để tránh dấu phẩy nhỏ ngu ngốc đó. Về khả năng mở rộng YMMV, hãy xem ví dụ này jsfiddle.net/oriadam/mywL9384 Làm rõ: Giải pháp của bạn rất tuyệt, tôi chỉ ghét thông số kỹ thuật cấm dấu phẩy.
oriadam

133

Không. Thông số JSON, như được duy trì tại http://json.org , không cho phép dấu phẩy. Từ những gì tôi đã thấy, một số trình phân tích cú pháp có thể âm thầm cho phép họ khi đọc chuỗi JSON, trong khi những người khác sẽ đưa ra lỗi. Để có khả năng tương tác, bạn không nên bao gồm nó.

Mã ở trên có thể được cấu trúc lại, để xóa dấu phẩy khi thêm dấu kết thúc mảng hoặc thêm dấu phẩy trước các mục, bỏ qua dấu phẩy đầu tiên.


1
ECMA 262 Có vẻ như định nghĩa nó trong phần 11.1.5-Trình khởi tạo đối tượng. Điều này có tốt hay không, dường như nằm trong thông số kỹ thuật.
Không phân tâm

6
Là ECMAScript hợp lệ không nhất thiết có nghĩa là một tài liệu là JSON hợp lệ - JSON thường được định nghĩa trong RFC 4627 và thông số đó không cho phép dấu phẩy.
Tim Gilbert

1
@ZeroDistraction: ECMA262 định nghĩa ECMAscript (còn được gọi là javascript) là ngôn ngữ lập trình như Perl hoặc Ruby hoặc C ++ hoặc Java. JSON là một định dạng dữ liệu như XML hoặc CSV hoặc YAML. Chúng không giống nhau. JSON không tồn tại trong EXMA262 nhưng cú pháp bắt nguồn từ đó và nó được gọi là ký hiệu nghĩa đen của đối tượng (ON trong JSON).
slebetman

106

Đơn giản, rẻ tiền, dễ đọc và luôn hoạt động bất kể thông số kỹ thuật.

$delimiter = '';
for ....  {
    print $delimiter.$whatever
    $delimiter = ',';
}

Việc gán dự phòng cho $ delim là một cái giá rất nhỏ phải trả. Cũng hoạt động tốt như vậy nếu không có vòng lặp rõ ràng nhưng các đoạn mã riêng biệt.


1
Đó là những gì tôi thường làm trong những tình huống như thế này; Tôi cảm thấy việc gán thêm nhiều hơn bù đắp bằng cách loại bỏ điều kiện cần thiết để nối thêm dấu phẩy trước giá trị trong phương pháp thay thế ( stackoverflow.com/a/201856/8946 ).
Lawrence Dol

5
Tôi không thích giải pháp này, vì có một biến số khác làm ô nhiễm phạm vi của tôi. Một iflà dễ dàng hơn để nắm bắt. Nhưng cảm ơn đã chia sẻ.
Ich

3
Ngoài ra, tốt hơn là chứa phạm vi của dải phân cách:for(let ..., sep=""; ... ; sep=",") { ...
Lawrence Dol

1
Tôi thích cách tiếp cận này vì nó tránh được các điều kiện, mặc dù các CPU hiện đại có logic dự đoán nhánh tốt. Xem thêm Tại sao xử lý một mảng được sắp xếp nhanh hơn một mảng chưa sắp xếp?
Hossein

21

Dấu phẩy được phép trong JavaScript, nhưng không hoạt động trong IE. Thông số JSON không phiên bản của Douglas Crockford không cho phép họ và vì nó không có phiên bản nên điều này không được phép thay đổi. Thông số JSON của ES5 cho phép chúng như một phần mở rộng, nhưng RFC 4627 của Crockford thì không, và ES5 đã hoàn nguyên để không cho phép chúng. Firefox theo sau. Internet Explorer là lý do tại sao chúng ta không thể có những thứ tốt đẹp.


1
Tôi chỉ thử chúng trong IE 11 mà không có vấn đề gì. Những phiên bản IE nào bạn đã thử nghiệm, nơi bạn tìm thấy chúng gây ra sự cố?
iconoclast

10
Có vẻ như Crockford là lý do tại sao chúng ta không thể có những điều tốt đẹp. Điều đó và nhận xét trong JSON
Hejazzman

Tại sao lại đề cập đến trình duyệt web khi OP sử dụng C ++ như mã giả? Không chắc là câu hỏi của OP có liên quan đến trình duyệt web hay JavaScript.
chăn bò

@cowlinator J ava S cript O bject N otation
forresthopkinsa

1
Các đối tượng Javascript đã lấy cảm hứng từ định dạng này, nhưng JSON không dành cho các công cụ Javascript
cowlinator

13

Như đã nói, thông số JSON (dựa trên ECMAScript 3) không cho phép dấu phẩy. ES> = 5 cho phép nó, vì vậy bạn thực sự có thể sử dụng ký hiệu đó trong JS thuần túy. Điều đó đã được tranh luận và một số trình phân tích cú pháp đã hỗ trợ nó ( http://bolinfest.com/essays/json.html , http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas- không còn được chấp nhận / ), nhưng đó là sự thật cụ thể (như được hiển thị trên http://json.org/ ) rằng nó không nên hoạt động trong JSON. Điều đó đã nói ...

... Tôi tự hỏi tại sao không ai chỉ ra rằng bạn thực sự có thể phân chia vòng lặp ở lần lặp thứ 0 và sử dụng dấu phẩy hàng đầu thay vì theo dõi để loại bỏ mùi mã so sánh và bất kỳ chi phí hiệu năng thực tế nào trong vòng lặp, dẫn đến một mã thực sự ngắn hơn, đơn giản hơn và nhanh hơn (do không có phân nhánh / điều kiện trong vòng lặp) so với các giải pháp khác được đề xuất.

Ví dụ: (trong mã giả kiểu C tương tự như mã đề xuất của OP):

s.append("[");
// MAX == 5 here. if it's constant, you can inline it below and get rid of the comparison
if ( MAX > 0 ) {
    s.appendF("\"%d\"", 0); // 0-th iteration
    for( int i = 1; i < MAX; ++i ) {
        s.appendF(",\"%d\"", i); // i-th iteration
    }
}
s.append("]");

3
Mẫu mã đơn giản và nhanh chóng. Tốt hơn nhiều so với các giải pháp khác được đề xuất.
Trevor Jex

12

Các lập trình viên PHP có thể muốn kiểm tra implode () . Điều này có một mảng kết hợp nó bằng cách sử dụng một chuỗi.

Từ các tài liệu ...

$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone

2
Tương tự, JavaScript đã tham gia () . Hầu hết các ngôn ngữ có một phương pháp tương tự, hoặc một ngôn ngữ tương tự có thể được mã hóa dễ dàng.
Dan Burton

16
PHP có json_encode, xử lý tất cả các chi tiết tạo JSON, không chỉ là dấu phẩy.
Brilliand

Thật tuyệt! Nó áp dụng cho JSON như thế nào và nó giúp OP giải quyết câu hỏi của họ như thế nào? Hãy nhớ rằng "Bạn có thể sử dụng dấu phẩy trong đối tượng JSON không?" là câu hỏi
Rockin4Life33

7

Thật thú vị, cả C & C ++ (và tôi nghĩ là C #, nhưng tôi không chắc chắn) đặc biệt cho phép dấu phẩy - vì chính xác lý do được đưa ra: Nó giúp việc tạo danh sách lập trình dễ dàng hơn nhiều. Không chắc chắn tại sao JavaScript không đi theo sự dẫn dắt của họ.


13
ECMA đã chỉ định rõ ràng rằng dấu phẩy được cho phép trong thông số sắp tới: ejohn.org/blog/orms-fixes-in-javascript-2 Tuy nhiên, một lý do khác để làm rõ rằng JSON! = Đối tượng JS.
mí mắt

PHP cũng cho phép nó. Tôi nghĩ đó là một tính năng của PHP mà tôi thích. ; p
iconoclast

4

Sử dụng JSON5. Đừng sử dụng JSON.

  • Các đối tượng và mảng có thể có dấu phẩy
  • Khóa đối tượng có thể không được trích dẫn nếu chúng là định danh hợp lệ
  • Chuỗi có thể được trích dẫn đơn
  • Chuỗi có thể được phân chia trên nhiều dòng
  • Các số có thể là thập lục phân (cơ sở 16)
  • Các số có thể bắt đầu hoặc kết thúc bằng dấu thập phân (dẫn đầu hoặc dấu).
  • Các số có thể bao gồm Infinity và -Infinite.
  • Các số có thể bắt đầu bằng dấu cộng (+) rõ ràng.
  • Cả hai bình luận nội tuyến (một dòng) và khối (nhiều dòng) đều được cho phép.

http://json5.org/

https://github.com/aseemk/json5


Có vẻ tốt, nhưng không thêm các loại dữ liệu mới có vẻ như là một cơ hội bị bỏ lỡ ... tất nhiên mong muốn duy trì một tập hợp con nghiêm ngặt của ECMAScript 5 buộc, nhưng vẫn ...
iconoclast

1
Ngoài ra, chuỗi mutliline là khủng khiếp. Tôi mơ về ES6 multilines.
Marco Sulla

10
Không, đó là lời khuyên HORRIBLE. Trong tất cả các thư viện JSON hiện có, rất ít hỗ trợ phần mở rộng như vậy; và tất cả điều này cho "cải tiến" rất đáng nghi ngờ. Vui lòng KHÔNG gây xói mòn thêm khả năng tương tác bởi các phần mở rộng không có thật mới như thế này.
StaxMan

8
Tôi tin rằng dành cả đời để sửa chữa dấu phẩy còn kinh khủng hơn.
dùng619271

3

Có một cách có thể để tránh một nhánh if trong vòng lặp.

s.append("[ "); // there is a space after the left bracket
for (i = 0; i < 5; ++i) {
  s.appendF("\"%d\",", i); // always add comma
}
s.back() = ']'; // modify last comma (or the space) to right bracket

2

Theo đặc tả Class JSONArray :

  • Một dấu phụ, (dấu phẩy) có thể xuất hiện ngay trước dấu ngoặc đóng.
  • Giá trị null sẽ được chèn khi có, (dấu phẩy).

Vì vậy, theo tôi hiểu, nó nên được phép viết:

[0,1,2,3,4,5,]

Nhưng điều có thể xảy ra là một số trình phân tích cú pháp sẽ trả về số 7 dưới dạng đếm vật phẩm (như IE8 như Daniel Earwicker đã chỉ ra) thay vì 6 như mong đợi.


Đã chỉnh sửa:

Tôi đã tìm thấy Trình xác thực JSON này xác nhận chuỗi JSON dựa trên RFC 4627 (Loại phương tiện ứng dụng / json cho Ký hiệu đối tượng JavaScript) và chống lại đặc tả ngôn ngữ JavaScript. Trên thực tế, ở đây một mảng có dấu phẩy được coi là hợp lệ chỉ dành cho JavaScript và không dành cho đặc tả RFC 4627.

Tuy nhiên, trong đặc tả RFC 4627 được nêu rằng:

2.3. Mảng

Một cấu trúc mảng được biểu diễn dưới dạng dấu ngoặc vuông bao quanh 0 hoặc nhiều giá trị (hoặc phần tử). Các yếu tố được phân tách bằng dấu phẩy.

array = begin-array [ value *( value-separator value ) ] end-array

Đối với tôi đây lại là một vấn đề giải thích. Nếu bạn viết rằng các phần tử được phân tách bằng dấu phẩy (không nêu rõ điều gì về các trường hợp đặc biệt, như phần tử cuối cùng), thì có thể hiểu theo cả hai cách.

PS RFC 4627 không phải là một tiêu chuẩn (như đã nêu rõ ràng) và đã bị RFC 7159 (đó là một tiêu chuẩn đề xuất) RFC 7159


6
Các quy tắc ngữ pháp được đưa ra là chính xác như bạn có thể nhận được. Không có cách nào để có một value-separatormà không có valuequyền bên cạnh nó. Ngoài ra văn bản rất cụ thể. "Tách các giá trị" chỉ có thể áp dụng nếu có nhiều giá trị. Vì vậy, nếu bạn có hai giá trị cạnh nhau, chúng được phân tách bằng dấu phẩy. Nếu bạn có một giá trị (hoặc nếu bạn chỉ nhìn vào giá trị ở cuối), không có sự phân tách, do đó không có dấu phẩy.
Steffen Heil

1

Từ kinh nghiệm trong quá khứ của tôi, tôi thấy rằng các trình duyệt khác nhau xử lý các dấu phẩy trong JSON khác nhau.

Cả Firefox và Chrome đều xử lý tốt. Nhưng IE (Tất cả các phiên bản) dường như bị phá vỡ. Tôi có nghĩa là thực sự phá vỡ và ngừng đọc phần còn lại của kịch bản.

Hãy ghi nhớ điều đó và thực tế là việc viết mã tuân thủ luôn luôn tốt, tôi khuyên bạn nên dành thêm nỗ lực để đảm bảo rằng không có dấu phẩy.

:)


1

Tôi giữ một số lượng hiện tại và so sánh nó với tổng số. Nếu tổng số hiện tại nhỏ hơn tổng số, tôi sẽ hiển thị dấu phẩy.

Có thể không hoạt động nếu bạn không có tổng số trước khi thực hiện việc tạo JSON.

Sau đó, một lần nữa, nếu bạn sử dụng PHP 5.2.0 trở lên, bạn có thể định dạng phản hồi của mình bằng API JSON được tích hợp.


1

Với thư giãn JSON, bạn có thể có dấu phẩy hoặc chỉ để lại dấu phẩy . Họ là tùy chọn.

Không có lý do nào tại tất cả các dấu phẩy cần phải có mặt để phân tích một tài liệu giống như JSON.

Hãy xem thông số JSON được thư giãn và bạn sẽ thấy thông số JSON ban đầu 'ồn ào' như thế nào. Quá nhiều dấu phẩy và trích dẫn ...

http://www.relaxedjson.org

Bạn cũng có thể thử ví dụ của mình bằng trình phân tích cú pháp trực tuyến RJSON này và xem nó được phân tích cú pháp chính xác.

http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D


JSON thư giãn không phải là JSON về mặt kỹ thuật không áp dụng được.
dùng2864740

Bạn có thể chuyển đổi rjson sang và từ json, vì vậy nó hoàn toàn có thể áp dụng. Rất dễ dàng để thêm nó vào quy trình công việc của bạn quá.
Steven Spungin

Điều này làm cho giả định rằng người tiêu dùng xuôi dòng hiểu điều này không phải là JSON. Chuyển đổi sang JSON hợp lệ sẽ yêu cầu xóa dấu phẩy trong cả hai trường hợp.
dùng2864740

OP sử dụng một chuỗi để bắt đầu. Chuỗi có thể được phân tích cú pháp để json objectsử dụng JSON.parsehoặc bởi một thư viện sử dụng RJSON.parse. Tôi sẽ đồng ý với bạn nếu nguồn là một đối tượng, nhưng đó không phải là trường hợp ở đây. Tôi không thấy nơi nào trong câu hỏi nó đề cập đến downstreamviệc tiêu thụ một đối tượng hoặc chuỗi.
Steven Spungin

"Khi tạo thủ công một đối tượng hoặc mảng JSON , việc để lại dấu phẩy trên mục cuối cùng trong đối tượng hoặc mảng .. Điều này có được phép [ trong JSON ] không? - vì vậy, một lần nữa: trong khi đây là một định dạng thay thế thú vị, nó không phảiJSON và không áp dụng về mặt kỹ thuật cho câu hỏi về JSON . Không có gì để 'bảo vệ': đó là một đề xuất Z để đặt câu hỏi X.
user2864740

0

Tôi thường lặp qua mảng và đính kèm dấu phẩy sau mỗi mục trong chuỗi. Sau vòng lặp tôi xóa dấu phẩy cuối cùng một lần nữa.

Có lẽ không phải là cách tốt nhất, nhưng ít tốn kém hơn so với việc kiểm tra mỗi lần nếu đó là đối tượng cuối cùng trong vòng lặp tôi đoán.


0

Nó không được khuyến khích, nhưng bạn vẫn có thể làm một cái gì đó như thế này để phân tích nó.

jsonStr = '[0,1,2,3,4,5,]';
let data;
eval('data = ' + jsonStr);
console.log(data)


0

Vì một vòng lặp for được sử dụng để lặp qua một mảng hoặc cấu trúc dữ liệu lặp tương tự, chúng ta có thể sử dụng độ dài của mảng như được hiển thị,

awk -v header="FirstName,LastName,DOB" '
  BEGIN {
    FS = ",";
    print("[");
    columns = split(header, column_names, ",");
  }
  { print("  {");
    for (i = 1; i < columns; i++) {
      printf("    \"%s\":\"%s\",\n", column_names[i], $(i));
    }
    printf("    \"%s\":\"%s\"\n", column_names[i], $(i));
    print("  }");
  }
  END { print("]"); } ' datafile.txt

Với datafile.txt chứa,

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31

0

Như đã nêu nó không được phép. Nhưng trong JavaScript, đây là:

var a = Array()
for(let i=1; i<=5; i++) {
    a.push(i)
}
var s = "[" + a.join(",") + "]"

(hoạt động tốt trong Firefox, Chrome, Edge, IE11 và không cho phép trong IE9, 8, 7, 5)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.