रूबी - सरणी के लिए परीक्षण


265

सही तरीका क्या है:

is_array("something") # => false         (or 1)

is_array(["something", "else"]) # => true  (or > 1)

या इसमें वस्तुओं की गिनती प्राप्त करने के लिए?


7
क्या आप एक वास्तविक सरणी चाहते हैं, या केवल कुछ सरणी की तरह?
कैथी वैन स्टोन

1
रूबी में कोई प्रकार-सुरक्षा नहीं है। अपने वैरिएबल को ऐरे होने या न होने की चिंता न करें। विधि को यह मान लेना चाहिए कि यह है, और आगे बढ़ो और इस पर कॉल करें: my_array.count
user132447

कृपया अधिक मुहावरेदार रूबी के लिए zgchurch और DigitalRoss द्वारा उत्तर पढ़ें।
DanT

जवाबों:


516

आप शायद उपयोग करना चाहते हैं kind_of()

>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true

31
वहाँ भी है is_a?और instance_of?। देखें stackoverflow.com/questions/3893278/...
नाथन लांग

2
प्रकार की जाँच जावा के लिए है। आगे बढ़ो और बस चर पर कॉल गणना। सुनिश्चित करने के लिए विधि के अनुसार काम करने के लिए इकाई परीक्षण लिखें।
user132447

14
@ user132447 वास्तव में जावा सुरक्षित है, इसलिए आपको किसी भी प्रकार की जाँच करने की चिंता करने की आवश्यकता नहीं है
grinch

8
मैंने अब इसे कम कर दिया क्योंकि मुझे नहीं लगता कि रूबी जैसी भाषा में यह अच्छा अभ्यास है। @Zgchurch द्वारा उत्तर स्पष्ट रूप से प्रश्न के लिए एक बहुत अधिक मुहावरेदार दृष्टिकोण है। इस तरह के मामलों में, मुझे लगता है कि यह बहुत अधिक समझ में आता है और यह पता लगाने की कोशिश करता है कि ओपी का मतलब क्या है, बजाय इसके कि वह आँख बंद करके शॉटगन दे ...
Per Lundberg

1
आप kind_of?()अन्य समाधानों का उपयोग क्यों करना चाहेंगे ? दूसरों पर आपके उत्तर के लाभों पर कुछ स्पष्टीकरण भविष्य के पाठकों के लिए उपयोगी होगा।
AlbertEngelB

148

आप यकीन है कि यह कर रहे हैं की जरूरत है एक श्रृंखला होना चाहिए? आप उपयोग करने में सक्षम हो सकते हैं respond_to?(method)ताकि आपका कोड समान चीज़ों के लिए काम करे जो आवश्यक रूप से सरणियाँ नहीं हैं (हो सकता है कि कुछ अन्य महत्वपूर्ण चीज़)। यदि आपको वास्तव में एक की आवश्यकता है array, तो Array#kind\_of?विधि का वर्णन करने वाला पद सबसे अच्छा है।

['hello'].respond_to?('each')

1
इस मामले में मुझे यकीन है कि यह एक ऐरे होगा। लेकिन इस तरीके को जानकर भी अच्छा लगा। +1
बडीजियो

दिलचस्प विचार, मैं डेटा संरचना पर पुश / पॉप का उपयोग कर रहा हूं। क्या एरे के अलावा कुछ भी उन तरीकों पर प्रतिक्रिया देगा?
ड्रू

3
यदि आप कुछ और तरह की सरणी चाहते हैं, तो आप चाहें respond_to?(:to_ary)
एंड्रयू ग्रिम

21
सामान्य तौर पर, यह ओओ विकास के लिए एक अच्छा अभ्यास है। मैंने पढ़ा जहां किसी ने मूल रूप से कहा था: कल्पना न करें कि आप अपनी वस्तुओं पर तरीके बुला रहे हैं। आप उन्हें संदेश भेज रहे हैं। यदि कोई वस्तु आपके संदेश का जवाब देना जानती है, तो आपको परवाह नहीं है कि वह किस वर्ग की है, या क्या उसके पास नाम का कोई तरीका है, या क्या यह गतिशील रूप से method_missing के माध्यम से प्रतिक्रिया बना रहा है। महत्वपूर्ण बात यह है कि क्या यह आपके संदेश का जवाब दे सकता है? यह फ़ंक्शन और कार्यान्वयन के बेहतर अमूर्तता की अनुमति देता है। आप बाद में जिस वस्तु का उपयोग करते हैं, उसे बदल सकते हैं, जब तक कि यह अभी भी सही ढंग से प्रतिक्रिया करता है।
नाथन लॉन्ग

2
इसके साथ एकमात्र मुद्दा यह है कि मैं यह जांचना चाहता हूं कि क्या कोई अनुक्रमित चलने योग्य है, इसलिए सरणियां, लिंक की गई सूचियां आदि शांत होंगी, लेकिन मुझे हैश जैसे महत्वपूर्ण मूल्य भंडार नहीं चाहिए?
कोल्टन वोगे

58

Array,केवल एक-स्तर में परिवर्तित होने के लिए परीक्षण के बजाय Array,आपके कोड को केवल एक मामले को संभालने की आवश्यकता है।

t = [*something]     # or...
t = Array(something) # or...
def f *x
    ...
end

रूबी तुम क्यों अगर कुछ जानना चाहते हैं पर एक अनुमान ले जा रहा एक API जो एक वस्तु या वस्तुओं का एक सरणी ले जा सकते हैं मिलाना विभिन्न तरीकों से है, इसलिए, है किसी सरणी, मैं एक सुझाव है।

सूचक ऑपरेटर जादू के बहुत सारे शामिल है आप देख सकते हैं, या आप बस फोन कर सकते हैं Array(something)यदि आवश्यक हो तो जो किसी सरणी आवरण जोड़ देगा। यह [*something]इस एक मामले में समान है ।

def f x
  p Array(x).inspect
  p [*x].inspect
end
f 1         # => "[1]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"

या, आप पैरामीटर घोषणा में छप का उपयोग कर सकते हैं और फिर .flatten, आपको एक अलग प्रकार का कलेक्टर दे सकते हैं। (उस बात के लिए, आप .flattenऊपर भी कॉल कर सकते हैं।)

def f *x
  p x.flatten.inspect
end         # => nil
f 1         # => "[1]"
f 1,2       # => "[1, 2]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"
f [1,2],3,4 # => "[1, 2, 3, 4]"

और, धन्यवाद gregschlom , यह कभी-कभी केवल उपयोग करने के लिए तेज़ होता है Array(x)क्योंकि जब यह पहले से ही है तो इसे Arrayएक नई वस्तु बनाने की आवश्यकता नहीं है।


तो आप कह रहे हैं कि क्या यह एक एकल आइटम है जो इसे एक एकल आइटम के साथ एक सरणी बनाता है?

हाँ, और अगर यह पहले से ही एक सरणी है तो यह एक दूसरे सरणी आवरण को जोड़े बिना रखता है।
DigitalRoss

2
मत भूलना [*nil] => []:। तो आप एक खाली सरणी के साथ समाप्त हो सकते हैं।
क्रिस्टोफर ओजबेक

3
का उपयोग करना Array(foo)बहुत अधिक कुशल है[*foo]
gregschlom

23

[1,2,3].is_a? Array सत्य का मूल्यांकन करता है।


1
यह उन उत्तरों को जोड़ता है जो लगभग सात वर्षों से साइट पर हैं ..?
मार्टिन टूरनोइज

6
@Carpetsmoker एक संक्षिप्त जवाब नहीं है is_a?जो इस पूरे धागे में संदर्भ देता है। सबसे पास एक है [1,2,3].is_a? Enumerable। मुझे अभी भी लगता है कि यह जवाब देने के लायक है।
डिपोले_मोमेंट

4
तुम्हें पता है .. तुम वास्तव में सही हो ... मैंने कसम खाई थी कि मैंने वहाँ पहले देखा था: - / एक upvote है!
मार्टिन टूरनोइज

16

ऐसा लगता है कि आप आइटम के कुछ अवधारणा के बाद कुछ कर रहे हैं। मैं यह देखने की सलाह दूंगा कि क्या यह है Enumerable। यह भी अस्तित्व की गारंटी देता है #count

उदाहरण के लिए,

[1,2,3].is_a? Enumerable
[1,2,3].count

ध्यान दें कि, जबकि size, lengthऔर countसरणियों के लिए सभी काम, countयहाँ सही अर्थ है - (उदाहरण के लिए, 'abc'.lengthऔर 'abc'.sizeदोनों काम करते हैं, लेकिन 'abc'.countउस तरह काम नहीं करता है)।

सावधानी: एक स्ट्रिंग is_a है? Enumerable, इसलिए शायद यह वह नहीं है जो आप चाहते हैं ... ऑब्जेक्ट की तरह एक सरणी की आपकी अवधारणा पर निर्भर करता है।



6

का उपयोग करने पर भी विचार करें Array()। से रूबी समुदाय स्टाइल गाइड :

स्पष्ट ऐरे चेक या [* var] के बजाय एरे () का उपयोग करें, जब आप एक एरे के रूप में व्यवहार करना चाहते हैं, तो एक वेरिएबल के साथ व्यवहार करें, लेकिन आप निश्चित नहीं हैं कि यह एक सरणी है।

# bad
paths = [paths] unless paths.is_a? Array
paths.each { |path| do_something(path) }

# bad (always creates a new Array instance)
[*paths].each { |path| do_something(path) }

# good (and a bit more readable)
Array(paths).each { |path| do_something(path) }

यह एक हैश को पार करते समय अप्रत्याशित परिणाम देगा क्योंकि to_aप्रत्येक तर्क को नए सरणी में जोड़ा जाता है, इसलिए Array({id: 100})रिटर्न[[:id, 100]]
ब्रेंट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.