2015-12-29 6 views
10

पर कुंजी और मूल्य जोड़ने के लिए लेंस का उपयोग करना मैं एसन लेंस के साथ जेएसओएन में हेरफेर करने के साथ एक समस्या का पता लगाने के लिए संघर्ष कर रहा हूं। मेरा काम जेएसओएन में नेस्टेड ऑब्जेक्ट में कुंजी जोड़ने के समान सरल है। मैं की मौजूदा keyby साधन को बदलने में सक्षम था:नेस्टेड मानचित्र

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

लेकिन जब मैंने उसे नया कुंजी के साथ सौदा करने की कोशिश, यह सिर्फ चुपचाप इसे जोड़ पाने में विफल:

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

निश्चित रूप से यह मेरे कर रही है कुछ गलत है, लेकिन मुझे लगता है कि मैं वास्तव में समझने के लिए मन से बाहर हूं।

क्या आप कृपया मुझे सही दिशा में इंगित करेंगे?

धन्यवाद!

उत्तर

15

जैसा कि डेफ्यूअर ने नोट किया है, at नक्शे में सम्मिलित हो सकता है, जबकि key और ix यदि वे मौजूद हैं तो केवल ट्रैवर्स तत्व हैं। हम निम्नलिखित कर सकते हैं:

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

at एक लेंस Maybe element -s पर ध्यान केंद्रित है, और हम Just करने के लिए कुछ तत्व की स्थापना द्वारा सम्मिलित कर सकते हैं, और Nothing को निर्धारित करके हटा दें। at "c" ?~ String "foo"at "c" .~ Just (String "foo") जैसा ही है।

हम नेस्टेड आवेषण क्या करना चाहते हैं, तो हम non उपयोग कर सकते हैं एक डिफ़ॉल्ट मान परिभाषित करने के लिए डाला करने के लिए किया जा:

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

यह एक कौर है, इसलिए हम कुछ हिस्सों को अलग कर सकते हैं:

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

मेरे मामले और अतिरिक्त स्पष्टीकरण के लिए एक उदाहरण उदाहरण प्रदान करने के लिए धन्यवाद! – SkyWriter

3

keyix पर आधारित है, जिसका दस्तावेज इंगित करता है कि यह आपके इच्छित काम करने के लिए पर्याप्त शक्तिशाली नहीं है और Control.Lens.At.at पर इंगित करता है। मुझे पूरा यकीन है कि आपके लिए चाल चलनी चाहिए। मूल विचार यह है कि आप JSON टेक्स्ट को ऑब्जेक्ट में बदलने के लिए _Object प्रिज्म से शुरू करते हैं, फिर at key का उपयोग उस क्षेत्र में लेंस प्राप्त करने के लिए Maybe के रूप में करें। इसके बाद आप इसे Just पर बदल सकते हैं जो आप चाहते हैं।

यह तब तक बहुत अच्छा काम करेगा जब तक आप जिस मार्ग को लेना चाहते हैं, उसके साथ सभी ऑब्जेक्ट्स मौजूद हैं। यदि आप (संभावित रूप से) कुछ भी नहीं शुरू करना चाहते हैं और सिंगल-फील्ड ऑब्जेक्ट्स की श्रृंखला बनाना चाहते हैं, तो आपको चीजों को और अधिक परेशान करने की संभावना होगी। सौभाग्य से, आपको शायद ऐसा करने की आवश्यकता नहीं है।

+0

कारणों को इंगित करने के लिए धन्यवाद कि क्यों 'कुंजी' मेरे मामले के लिए काम नहीं करता है। मैंने वास्तव में स्रोत कोड को देखने की कोशिश की, लेकिन यह भी कम समझ में आता है :-) मान लीजिए कि इसके चारों ओर सिर पाने में समय लगता है। – SkyWriter

+0

@ स्काईवाइटर, यदि आप मॉडल/व्यू टर्मिनोलॉजी से परिचित हैं, तो आप '_Object' के बारे में सोच सकते हैं, 'टेक्स्ट' मॉडल का पूर्ण 'ऑब्जेक्ट'" व्यू "प्रदान करते हुए, लेकिन केवल तभी 'टेक्स्ट' सफलतापूर्वक पार हो जाता है 'Object'। विचार को समझने में सफल होने पर, आप उस दृश्य के माध्यम से 'टेक्स्ट' मॉडल का निरीक्षण और संशोधन कर सकते हैं। – dfeuer

संबंधित मुद्दे