Làm thế nào để biểu diễn một tập hợp trong JSON?


14

JSON hỗ trợ các cấu trúc dữ liệu sau (tương đương Java): Vô hướng, Mảng / Danh sách và Bản đồ.

A Setkhông được hỗ trợ ngoài hộp trong JSON.

Tôi đã nghĩ về một số cách để biểu diễn một tập hợp trong JSON:

[1] - Như một danh sách

Tuy nhiên, một danh sách có thứ tự riêng của nó, vì vậy hai danh sách sau đây ["a", "b"]["b", "a"]không bằng danh sách, nhưng chúng phải bằng nhau như bộ.

[2] - Như một bản đồ

Sử dụng bộ khóa của bản đồ và bỏ qua các giá trị.

Nhưng một lần nữa, bằng cách sử dụng so sánh tiêu chuẩn, cả hai không giống như bản đồ:

{"a": "foo", "b": "bar"}, {"a": null, "b": null}

[3] - Là bản đồ, có giá trị đặc biệt

Lấy một vô hướng, nói 0hoặc nullvà buộc nó là giá trị của mọi khóa trong bản đồ:

{"a": 0, "b": 0}

Bằng cách này, dưới các công cụ so sánh tiêu chuẩn, các đối tượng bằng nhau, ngay cả khi thứ tự khóa được thay đổi.

Tuy nhiên, kỹ thuật này gây ô nhiễm tài liệu JSON với dữ liệu không liên quan.

[4] - Như một danh sách được sắp xếp

Quay lại đề xuất đầu tiên, nhưng lần này là một danh sách theo thứ tự. Loại này giải quyết vấn đề so sánh.

Tuy nhiên, chúng ta cũng nên ghi nhớ sự phức tạp của việc sắp xếp và ký hiệu bản đồ đó xử lý các bản sao, trong khi một danh sách được sắp xếp thì không. Thí dụ:

{"a": 400, "a": 9}được xử lý như {"a": 9}, nhưng ["g", "g"]sẽ luôn luôn như vậy ["g", "g"].

Tôi đã nói tất cả những điều đó, dường như ký hiệu danh sách rõ ràng hơn, nhưng ký hiệu bản đồ mạnh hơn đối với sao chép khóa và khiến cho việc thống nhất về giá trị đặc biệt khó khăn hơn (mặc dù nullcó vẻ như là một lựa chọn tốt cho điều đó).

Bạn nghĩ sao? Làm thế nào bạn sẽ đại diện cho một bộ trong JSON?

PS

Lưu ý rằng câu hỏi này chỉ đơn thuần là về JSON. Tôi biết rằng các định dạng khác, như yaml, có sẵn. Vẫn...


1
Các bộ không được JSON hỗ trợ, nó nằm ngoài phạm vi. Một tập hợp, hoặc một bộ sưu tập riêng biệt, duy nhất, tồn tại trong phạm vi của ứng dụng. Bởi vì đó là một bộ sưu tập, nên sử dụng cú pháp bộ sưu tập sẽ rõ ràng hơn.
Zymus

1
Tại sao bạn muốn đại diện cho các bộ trong JSON? Hãy nhớ JSON là một định dạng trao đổi.
Andres F.

@AresresF. Tôi nghĩ rằng nó sẽ là một ý tưởng tốt để thể hiện thuộc tính duy nhất của các giá trị. Tôi sẽ không ràng buộc JSON chỉ với định dạng trao đổi. Nó cũng có thể hữu ích cho việc lưu trữ tài liệu (như trong MongoDB).
Ron Klein

@RonKlein Đủ công bằng. Nhưng ugh ... đừng để tôi bắt đầu với MongoDB: P
Andres F.

Trong YAML, các bộ được biểu diễn dưới dạng tùy chọn của bạn [3], nhưng nó có ký hiệu đặc biệt mà JSON không có.
Jasmijn

Câu trả lời:


20

Vâng, bạn không thể. Như bạn đã nói, bạn có thể đại diện cho mảng và từ điển. Bạn có hai lựa chọn.

Đại diện cho tập hợp như là một mảng. Ưu điểm: Chuyển đổi từ thiết lập sang mảng và trở lại thường dễ dàng. Nhược điểm: Một mảng có một thứ tự ngụ ý, mà một tập hợp không có, do đó, việc chuyển đổi các tập hợp giống hệt nhau thành các mảng JSON có thể tạo ra các mảng được coi là khác nhau. Không có cách nào để thực thi rằng các phần tử mảng là duy nhất, vì vậy một mảng JSON có thể không chứa một tập hợp lệ (rõ ràng bạn chỉ có thể bỏ qua các bản sao; đó là điều có thể xảy ra dù sao).

Biểu diễn tập hợp dưới dạng từ điển, với giá trị tùy ý cho mỗi khóa, ví dụ 0 hoặc null. Nếu bạn chỉ bỏ qua các giá trị, đây là một kết hợp hoàn hảo. Mặt khác, bạn có thể không có thư viện hỗ trợ để trích xuất các khóa của từ điển dưới dạng tập hợp hoặc để biến tập hợp thành từ điển.

Trong môi trường lập trình của tôi, việc chuyển đổi giữa tập và mảng trở nên dễ dàng hơn (mảng cần đặt sẽ mất các giá trị trùng lặp, không nên ở đó hoặc sẽ được coi là chính xác), vì vậy, vì lý do đó tôi sẽ đi theo mảng. Nhưng đó là rất nhiều vấn đề quan điểm.

NHƯNG: Có một con voi to béo trong phòng chưa được đề cập. Các khóa trong từ điển JSON chỉ có thể là chuỗi. Nếu tập hợp của bạn không phải là một chuỗi các chuỗi, thì bạn chỉ có lựa chọn sử dụng một mảng.


4
trường hợp cạnh của các chuỗi không phải là một đối số tốt đối với một từ điển.
Ron Klein

3

Đừng cố gắng biểu diễn các bộ trong JSON. Làm điều đó khi phân tích dữ liệu thay thế.

Dữ liệu JSON của bạn phải có một lược đồ chỉ định các trường nào sẽ được coi là một tập hợp hoặc bạn có thể có một siêu dữ liệu được nhúng trong chính dữ liệu JSON mô tả khi một danh sách nên được coi là một tập hợp (ví dụ {"houses": {"_type": "set", "value": [...]}}) hoặc theo quy ước đặt tên.

Lưu ý rằng theo tiêu chuẩn JSON, một đối tượng JSON có thể có các khóa trùng lặp. Từ ECMA-404:

Các đối tượng

[...] Cú pháp JSON không áp đặt bất kỳ hạn chế nào đối với các chuỗi được sử dụng làm tên, không yêu cầu các chuỗi tên đó là duy nhất và không gán bất kỳ ý nghĩa nào cho việc sắp xếp các cặp tên / giá trị. Đây là tất cả các cân nhắc về ngữ nghĩa có thể được xác định bởi các bộ xử lý JSON hoặc trong các đặc tả xác định việc sử dụng JSON cụ thể để trao đổi dữ liệu.

AFAICD, không có gì trong thông số kỹ thuật cấm các tên không phải là duy nhất và có nhiều triển khai trình phân tích cú pháp JSON có thể phân tích các tên đối tượng không duy nhất. RFC 7159 không khuyến khích các tên không phải là duy nhất cho khả năng tương tác, nhưng đặc biệt không cấm nó, và tiếp tục liệt kê cách các trình phân tích cú pháp khác nhau đã được nhìn thấy xử lý các tên đối tượng không phải là duy nhất.

Và ECMA 404 cũng không yêu cầu bảo toàn thứ tự mảng:

Mảng

Cú pháp JSON không định nghĩa bất kỳ ý nghĩa cụ thể nào đối với thứ tự của các giá trị. Tuy nhiên, cấu trúc mảng JSON thường được sử dụng trong các tình huống có một số ngữ nghĩa để đặt hàng.

Từ ngữ này cho phép các ứng dụng sử dụng mảng để biểu diễn các tập hợp nếu chúng chọn.

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.