2010-10-01 13 views
7

बनाती है मैं रूबी सीख रहा हूं और अभी सरणी और श्रेणियों के बारे में कुछ सामान प्राप्त कर चुका हूं। मैंने स्लाइस के बारे में कुछ में भाग लिया है, जबकि पहली नज़र में यह समझ में आता है, जब मैं इसमें गहराई से देखता हूं तो मुझे थोड़ा सा भ्रमित करता है।रूबी: रेंज खाली है, लेकिन इसके साथ स्लाइसिंग तत्व

IRB कहता है कि (2..-1).to_a एक खाली सरणी है, जिसका मतलब सीमा में कोई मान नहीं है, है ना?
लेकिन यदि मैं [:a, :b, :c, :d, :e][2..-1] में उसी श्रेणी का उपयोग करता हूं, तो मुझे खाली सरणी के बजाय [:c, :d, :e] वापस मिल जाता है।

अब, मुझे पता है कि -1 सरणी के अंतिम तत्व का प्रतिनिधित्व करता है, इसलिए यह समझ में आता है कि क्या चुना गया, किया। लेकिन अगर सीमा खाली हो जाएगी, तो यह कुछ भी कैसे चुन रहा है?

उत्तर

11

यह एक आकर्षक सवाल है। जवाब यह है कि यह उस श्रेणी के अलग-अलग तत्व नहीं हैं जिनका परीक्षण किया जाता है जब सरणी को टुकड़ा करते समय निरीक्षण किया जाता है, लेकिन first और last तत्व। विशेष रूप से:

>> (2..-1).to_a 
=> [] 
>> (2..-1).first 
=> 2 
>> (2..-1).last 
=> -1 

इस प्रकार उदाहरण के काम करता है, के बाद से यह [-1] तत्व को [2] तत्व से सरणी स्लाइस।

आप इस बारे में सोचने के लिए एक सुसंगत तरीका चाहते हैं, विचार है कि (2..-1).to_a आउटपुट पूर्णांकों 2 और -1 (जिनमें से वहाँ कोई नहीं कर रहे हैं) के बीच पाया है, लेकिन है कि [2..-1]2सूचकांक से -1सूचकांक का मतलब ।

(स्रोत: array.c और range.c रूबी स्रोत में।)

और, जटिल बोनस हिस्सा: अर्थ आप के बारे में सोच रहे थे प्राप्त करने के लिए, आप इस्तेमाल कर सकते हैं

>> [:a, :b, :c, :d, :e].values_at *(2..-1).to_a 
=> [] 
+0

भविष्य में संदर्भ के लिए, क्या है '* (2 ..- 1) .to_a' में स्टार? – cHao

+0

जो 'स्प्लट' ऑपरेटर होगा। – Peter

+2

अधिक सटीक: 'foo ([1,2,3])' कॉल 'foo' एक (सूची) तर्क के साथ। 'foo (* [1,2,3]) 'इसे तीन के साथ कॉल करता है: यह' foo (1,2,3) 'के बराबर है; सूची deconstructed है और इसके तत्व समारोह कॉल पर बिखरे हुए हैं। – Amadan

3

टुकड़ा करने की क्रिया आपरेशन में यह एक Range से प्रति के रूप में सीमा नहीं देख रहा है, यह सिर्फ, अंतिम बिंदु के मूल्यों को देख रहा है इस मामले 2 और -1 में। चूंकि -1 का एक विशेष अर्थ है (यानी सूची में अंतिम आइटम) यह सूची के अंत में इंडेक्स 2 पर आइटम से सब कुछ देता है। इसे Range के रूप में न सोचें, बस इसे दो संख्याओं में पारित करने के सुविधाजनक तरीके के रूप में सोचें (दो अंत बिंदुओं को व्यक्त करना)।

1

Array#[] विधि करता है श्रेणी को एक श्रेणी के रूप में उपयोग न करें (यानी, यह include? पर या उस तरह कुछ भी नहीं कहता है); यह सिर्फ दो संख्याओं को लेता है और जांच करता है कि यह अनन्य है या नहीं।

आप इसे कल्पना कर सकते हैं इस तरह कुछ हद तक देखने के लिए (हालांकि वास्तविक [] सी में कार्यान्वित किया जाता है, Ruby में नहीं, और निश्चित रूप से भी पर्वतमाला के अलावा अन्य तर्क संभालती है):

def [](range) 
    start = range.begin 
    length = range.end - start 
    length -= 1 if range.exclude_end? 
    slice(start, length) 
end 
संबंधित मुद्दे