Cấu trúc JSON nào để sử dụng cho các cặp giá trị chính?


23

Định dạng JSON nào là lựa chọn tốt hơn cho các cặp giá trị chính và tại sao?

[{"key1": "value1"}, {"key2": "value2"}]

Hoặc là:

[{"Name": "key1", "Value": "value1"}, {"Name": "key2", "Value": "value2"}]

Hoặc là:

{"key1": "value1", "key2": "value2"}

Biến thể đầu tiên có vẻ nhỏ gọn hơn và "có ý nghĩa về mặt ngữ nghĩa" hơn. Biến thể thứ hai dường như có cấu trúc đồng đều hơn có thể giúp xử lý nó. Các biến thể thứ 3 dường như thậm chí nhiều ngữ nghĩa hơn.

Các cặp giá trị khóa sẽ được sử dụng để đính kèm dữ liệu tùy ý vào một số mục khác. Dữ liệu phải được tuần tự hóa dưới dạng JSON để làm tròn dữ liệu thông qua một hệ thống.


3
Trừ khi bạn yêu cầu đặt hàng, tại sao không xem xét {"key1": "value1", "key2": "value2"}?
kennytm

4
JSON đã là một từ điển (lồng nhau).
Kasey speakman

1
Vấn đề của bạn là mô tả đủ rộng để nói rằng bất kỳ định dạng nào cũng sẽ hoạt động và câu hỏi thực sự là làm thế nào để tiêu thụ đơn giản hơn, điều này phụ thuộc vào công nghệ mà khách hàng sử dụng.
scriptin

Bạn nên sử dụng đơn giản nhất đáp ứng nhu cầu của bạn, hy vọng đó sẽ là dạng đối tượng đơn giản (# 3). Tuy nhiên, nếu bạn đang tìm kiếm nhiều tùy chọn hơn nữa, bạn có thể sử dụng song song hai mảng, một cho các khóa và một cho các giá trị; nó sẽ nhỏ gọn nhất có thể trong khi vẫn hỗ trợ các khóa đối tượng & các khóa trùng lặp (không được hỗ trợ với # 3).
Erik Eidt

Câu trả lời:


10

Việc bạn chọn tùy chọn thứ nhất hay thứ ba tùy thuộc vào trường hợp sử dụng của bạn. Nếu bạn đang mô hình hóa nhiều trường hợp khác nhau của cùng một loại điều, hãy chọn điều đầu tiên. Ví dụ, bạn có một danh sách những người. Nếu bạn đang mô hình hóa nhiều thuộc tính khác nhau của một thứ, hãy chọn thứ ba. Bạn có thể có các phím lặp lại ở định dạng đầu tiên, nhưng không phải ở khóa thứ ba.

Tùy chọn thứ hai là khủng khiếp và tôi vẫn chưa tìm thấy trường hợp sử dụng thích hợp cho nó. Lý do thật tồi tệ, ngoài việc dài dòng hơn, là vì JSON đơn cấp, nó phá vỡ hầu hết các chuyển đổi tự động của thư viện thành từ điển / bản đồ. Đối với JSON được lồng sâu, nó phá vỡ giao diện truy vấn giống XPath .

Điều này làm cho nó một nỗi đau để làm việc với. Và nếu bạn không biết các khóa của mình tại thời gian biên dịch, bạn sẽ muốn có một giao diện từ điển hoặc XPath, vì bạn sẽ không thể chuyển đổi nó thành một lớp. Bây giờ nó có vẻ không phải là một vấn đề lớn, nhưng bạn có định dạng dữ liệu càng lâu thì càng khó thay đổi.


5
Ưu điểm lớn của tùy chọn thứ hai là nó hoạt động với các phím không có chuỗi, đặc biệt là các phím tổng hợp.
CodeInChaos

1
Tùy chọn thứ hai là khủng khiếp và bạn vẫn chưa tìm thấy trường hợp sử dụng? Mảng từ điển có nhiều cặp khóa / giá trị phải là định dạng phổ biến nhất để truyền nhiều đối tượng.
gnasher729

2
@ gnasher729, trong trường hợp "định dạng phổ biến nhất" của bạn, các phím thực đều nằm ở phía bên trái : [{"key1": "value1", "key2": "value2"}]. Định dạng thứ hai ở đây là đặt khóa thực ở phía bên tay phải và sử dụng một khóa khác có tên "Tên" để trỏ bạn đến khóa thực, khiến việc phân tích bằng các công cụ tiêu chuẩn trở nên vô cùng khó khăn.
Karl Bielefeldt

Tôi sẽ cung cấp cho bạn cái đó, @CodesInChaos. Mặc dù ở đó, mặc dù, nó sẽ phải là một trường hợp rất đặc biệt. Tôi chưa bao giờ thấy sự cần thiết của nó trong tự nhiên.
Karl Bielefeldt

3
Xin lỗi, nhưng đây là một câu trả lời xấu. Tùy chọn thứ 2 là cả rất phổ biến được sử dụng và khuyên. Nó cho phép các khóa linh hoạt, nó cho phép mở rộng (với nhiều trường giá trị / siêu dữ liệu hơn) mà không phá vỡ người tiêu dùng và nó có thể duy trì thứ tự phần tử. Ngoài ra, các lý do được đưa ra là không có thật: nó không phá vỡ bất kỳ "chuyển đổi tự động" nào (nó chỉ tôn trọng phần trình bày của tác giả dưới dạng mảng) và nó hoạt động tốt với giao diện truy vấn giống như XPath. Nhược điểm duy nhất là độ dài tăng.
Hejazzman

5

Định dạng thứ 3 nói chung là tốt nhất. Tuy nhiên, đây là một ví dụ về một cái gì đó phù hợp cho định dạng 1:

[{
  "username": "foo",
  "id": 1
}, {
  "username": "bar",
  "id": 2
}, {
  "username": "baz",
  "id": 3
}]

Ở đây mỗi đối tượng đề cập đến một điều riêng biệt (và mỗi đối tượng sử dụng các khóa giống như các đối tượng khác, vì vậy chúng không thể được hợp nhất). Tuy nhiên, mỗi đối tượng trong danh sách được lưu trữ { "username": "foo", "id": 1 }thay [{ "username": "foo" }, { "id": 1 }]vì vì 1) nó ngắn hơn và 2) nó đề cập đến một điều với tên người dùng và id, không phải là một điều với tên người dùng và một điều khác với id.

Vấn đề với tùy chọn thứ hai là nó trở nên rất dài dòng như là JSON và để làm việc với. Tuy nhiên, nó có thể được sử dụng nếu bạn cần lưu trữ thông tin meta về tài sản. Một ví dụ:

{
  "key": "foo",
  "value": 1,
  "mutable": true
}

Ở đây mutableđề cập đến một trường hợp giả thuyết về việc bạn có thể sửa đổi chính tài sản đó chứ không phải đối tượng cha. Thông tin meta như thế này tương tự như JavaScript Object.defineProperty, nơi lưu trữ thông tin "có thể định cấu hình", "có thể đếm được" và "có thể ghi" về một thuộc tính.


Tôi đã cố gắng sử dụng định dạng đầu tiên cho một số JSON mà tôi đã gửi đến điểm cuối C # REST và nó không chuyển đổi thành đối tượng từ điển. Chuyển đổi nó sang định dạng thứ 3 đã xóa nó lên.
fizch

5

Bạn nói đây là những cặp khóa / giá trị. Trong trường hợp đó, sử dụng # 3: dictionary của các cặp khóa / giá trị.

Nếu đây không phải là cặp khóa / giá trị, thì đừng gọi chúng là "khóa" và "giá trị" và sử dụng # 2, một mảng từ điển có nội dung tùy ý.

Cấu trúc # 1 chỉ là daft trừ khi bạn cần các cặp khóa / giá trị mà còn theo thứ tự của chúng. Mà bạn hiếm khi làm.


3

Đặt bản thân của bạn vào vị trí của người nhận json. Nếu tôi không biết tên khóa, làm thế nào tôi có thể lấy nó với định dạng đầu tiên hoặc cuối cùng? Tất nhiên bạn có thể lặp qua json nhưng vì cả ba định dạng đều đạt được cùng một kết quả nên đó chỉ là một câu hỏi về cú pháp. Tôi nghĩ rằng đây là câu hỏi có ý nghĩa duy nhất: nếu bạn biết tên chính thì tùy chọn thứ nhất hoặc cuối cùng nhỏ gọn hơn, nếu không lựa chọn thứ hai thì dễ hiểu hơ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.