2012-04-27 13 views
6

मुझे यकीन है कि मैं पहले यह करने के लिए एक सुरुचिपूर्ण समाधान देखा है, लेकिन मैं काफी यह नहीं मिल रहा कर सकते हैं:सुंदर ढंग से एक नेस्टेड हैश में रिक्त मानों से निपटने

मैं एक रेल नियंत्रक जो हो सकता है या हो सकता है - निम्नलिखित हैश तत्व नहीं है:

myhash[:parent_field] 

उस मूल क्षेत्र के अंदर, एक बच्चा तत्व भी खाली हो सकता है। मैं वर्तमान में (बहुत बदसूरत) विधि के माध्यम से है कि जाँच कर रहा हूँ:

if (!myhash[:parent_field] || !myhash[:parent_field][:child_field] || myhash[:parent_field][:child_field].blank?) 

कौन सा काम करता है, लेकिन मैं समझ - निश्चित रूप से - वहाँ एक और अधिक सुरुचिपूर्ण तरीका हो गया है। बस दोहराते हैं:

  • myhash [: parent_field] या
  • मौजूद नहीं हो सकता है यह मौजूद है, तो myhash [: parent_field] [: child_field] या मौजूद हो सकता है हो सकता है नहीं
  • अगर वह मौजूद है, यह खाली हो सकता है या नहीं हो सकता है।

उत्तर

9

#fetch अपने दोस्त है:

my_hash.fetch(:parent, {})[:child].blank? 
+0

ध्यान दें कि यह 'अपवाद उठाएगा यदि' पैरेंट' कुंजी मौजूद नहीं है। –

+0

@AndrewMarshall नहीं यह नहीं होगा। क्या लाता है पर पढ़ें। – d11wtq

+0

क्षमा करें, वहां दूसरे तर्क को नहीं देखा। अगर ऐसा नहीं होगा, हालांकि। –

0

यह शायद अपने वास्तविक जरूरतों क्या कर रहे हैं पर निर्भर करता है, लेकिन यह करने के लिए एक OOP दृष्टिकोण सरणियों कन्वर्ट करने के लिए हो सकता है और वास्तविक वस्तुओं में हैश। प्रत्येक वस्तु अपने रिश्तों को प्रबंधित करेगी (ActiveRecord के समान), और बच्चों और माता-पिता को कैसे प्राप्त करें, यह जान लेंगे।

3

मैं करना होगा क्या सिर्फ स्थानीय चर का उपयोग कर रहा है अपने बोझ को कम करने के लिए:

unless (p=foo[:parent]) && (c=p[:child]) && !c.blank? 
    # Stuff is borked! 
end 

लेकिन विकल्प, मज़ा है & hellip के लिए पता लगाने;


आप अपने डेटा संरचना (कि, एक हैश है जिस तरह से, नहीं किसी सरणी से) तो आप रेल 'try बुलाने की के रूप में आलसी तरीके के साथ संयोजन के रूप में रूबी andand मणि उपयोग कर सकते हैं बदल नहीं सकते हैं उन चीज़ों पर विधियां जो nil ऑब्जेक्ट्स हो सकती हैं।


आप वैकल्पिक रूप से Hashes कि वापसी खाली ऑटो vivifying हैश जब आप एक कुंजी के लिए पूछना जो मौजूद नहीं है करने के लिए अपने डेटा संरचना को बदल सकता है:

mine = Hash.new{ |h,k| Hash.new(&h.default_proc) } 
mine[:root] = { dive:42 } 
p mine[:root][:dive]  #=> 42 
p mine[:ohno][:blah][:whee] #=> {} 
p mine[:root][:blah][:whee] #=> undefined method `[]' for nil:NilClass (NoMethodError) 

लेकिन, आप यह सुनिश्चित करें कि होगा आपके पदानुक्रम में प्रत्येक वस्तु इन हैश में से एक थी (जिसे मैं :dive की सामग्री के लिए स्पष्ट रूप से विफल रहा, जिसके परिणामस्वरूप त्रुटि हुई)।


विकल्प मस्ती के लिए, आप अपने खुद के जादू देखने विधि जोड़ सकते हैं:

class Hash 
    def divedive(*keys) 
    obj = self 
    keys.each do |key| 
     return obj unless obj && obj.respond_to?(:[]) 
     obj = obj[key] 
    end 
    obj 
    end 
end 

if myarray.divedive(:parent,:child).blank? 
    # ... 
-2

कैसे के बारे में

!(myarray[:parent_field][:child_field] rescue nil).blank? 

?

0

nil.blank?true है के बाद से, आप बीच शर्त को हटा सकते हैं और आसान बनाने में यह करने के लिए:

if !myarray[:parent_field] || myarray[:parent_field][:child_field].blank? 

इसके अलावा, बुला एक हैश myarray थोड़ा भ्रामक है।

1

यह एक अक्सर पूछे जाने वाले प्रश्न है और शायद

कि सूची में पहले के डुप्लिकेट के रूप बंद किया जाना चाहिए एक dup के रूप में बंद हो गया अन्य दो में से, हालांकि मेरा मानना ​​है कि मेरे उत्तर में बाद में दो की तुलना में इस समस्या को हल करने के लिए तकनीकों का अधिक व्यापक कवरेज है ओ।

+0

अरे - तुम सही हो। मैंने खोज करने की कोशिश की, लेकिन कुछ भी प्रासंगिक नहीं लाया। मैंने बंद करने के लिए मतदान किया है। और बहुत धन्यवाद। :-) – PlankTon

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