2015-12-29 22 views
10

Tôi đang cố gắng tìm ra một vấn đề với thao tác JSON bằng ống kính Aeson. Nhiệm vụ của tôi cũng đơn giản là thêm một khóa vào một đối tượng lồng nhau trong JSON. Tôi đã có thể thay đổi các phương tiện keyby hiện của:Sử dụng ống kính để thêm khóa và giá trị vào Bản đồ lồng nhau

> :set -XOverloadedStrings 
> import Control.Lens 
> import Data.Aeson 
> import Data.Aeson.Lens 
> "{ \"a\": { \"b\": 10 } }" & key "a" . key "b" .~ String "jee" 
"{\"a\":{\"b\":\"jee\"}}" 

Nhưng khi tôi cố gắng để làm cho nó đối phó với chìa khóa mới, nó chỉ âm thầm không thêm nó:

> "{ \"a\": { \"b\": 10 } }" & key "a" . key "c" .~ String "jee" 
"{\"a\":{\"b\":10}}" 

Chắc chắn đó là tôi làm một cái gì đó sai, nhưng tôi hình tôi ra khỏi mana để hiểu chính xác những gì.

Bạn vui lòng chỉ cho tôi đúng hướng không?

Cảm ơn bạn!

Trả lời

15

Như đã lưu ý, at có thể chèn vào bản đồ, trong khi keyix chỉ đơn thuần là đi qua các phần tử nếu chúng tồn tại. Chúng ta có thể làm như sau:

> "{ \"a\": { \"b\": 10 } }" & key "a" . _Object . at "c" ?~ String "foo" 
"{\"a\":{\"b\":10,\"c\":\"foo\"}} 

at là một thấu kính hội tụ trên Maybe element -s, và chúng ta có thể chèn bằng cách thiết lập để Just một số yếu tố, và loại bỏ bằng cách thiết lập để Nothing. at "c" ?~ String "foo" giống với at "c" .~ Just (String "foo").

Nếu chúng ta muốn làm chèn lồng nhau, chúng ta có thể sử dụng non để xác định một giá trị mặc định được chèn vào:

> "{ \"a\": { \"b\": 10 } }" & key "a" . _Object . at "c" . non (Object mempty) . _Object . at "d" ?~ String "foo" 
"{\"a\":{\"b\":10,\"c\":{\"d\":\"foo\"}}}" 

Đây là một mouthful, vì vậy chúng tôi có thể yếu tố một số bộ phận ra:

> let atKey k = _Object . at k 
> "{ \"a\": { \"b\": 10 } }" & key "a" . atKey "c" . non (Object mempty) . atKey "d" ?~ String "foo" 
+0

Cảm ơn bạn đã cung cấp một ví dụ làm việc cho trường hợp của tôi và giải thích thêm! – SkyWriter

3

key được dựa trên ix, có tài liệu cho biết nó không đủ mạnh để thực hiện những gì bạn muốn và trỏ tới Control.Lens.At.at. Tôi khá chắc chắn rằng nên làm các trick cho bạn. Ý tưởng cơ bản là bạn bắt đầu với lăng kính _Object để biến văn bản JSON thành đối tượng, sau đó sử dụng at key để lấy ống kính vào trường đó dưới dạng Maybe. Sau đó, bạn có thể thay đổi nó thành Just những gì bạn muốn.

Điều này sẽ hoạt động rất tốt miễn là tất cả các đối tượng dọc theo đường dẫn bạn muốn tồn tại. Nếu bạn muốn (có khả năng) bắt đầu từ không có gì và tạo ra một chuỗi các đối tượng đơn trường, bạn sẽ có thể tìm thấy những điều khó chịu hơn. May mắn thay, bạn có thể không cần phải làm điều này.

+0

Cảm ơn bạn đã chỉ ra lý do tại sao 'khóa' không hoạt động đối với trường hợp của tôi. Tôi thực sự cố gắng nhìn vào mã nguồn, nhưng nó thậm chí còn ít ý nghĩa hơn :-) Đoán rằng phải mất thời gian để có được đầu xung quanh điều này. – SkyWriter

+0

@SkyWriter, nếu bạn quen thuộc với thuật ngữ mô hình/xem, bạn có thể nghĩ '_Object' như cung cấp một khung nhìn' Object' hoàn chỉnh 'của mô hình 'Văn bản', nhưng chỉ khi' Văn bản' phân tích cú pháp thành công như một 'Object'. Giả sử khung nhìn thành công, bạn có thể kiểm tra và sửa đổi mô hình 'Text' thông qua khung nhìn đó. – dfeuer

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