रूबी प्रत्येक_विथ_इंडेक्स ऑफसेट


84

क्या मैं प्रत्येक_with_index लूप पुनरावृत्त में सूचकांक की भरपाई को परिभाषित कर सकता हूं? मेरा सीधा आगे का प्रयास विफल रहा:

some_array.each_with_index{|item, index = 1| some_func(item, index) }

संपादित करें:

स्पष्टता: मैं नहीं चाहता कि एक सरणी ऑफसेट मैं चाहता हूं कि प्रत्येक के भीतर सूचकांक_विथ_ इंडेक्स 0 से शुरू न हो, लेकिन उदाहरण 1।


रूबी संस्करण का आप क्या उपयोग करते हैं?
fl00r

क्षमा नहीं लिख के लिए है, लेकिन मैं रूबी 1.9.2 का उपयोग
मार्क

जवाबों:


110

दरअसल, Enumerator#with_indexएक वैकल्पिक पैरामीटर के रूप में ऑफसेट प्राप्त होता है:

[:foo, :bar, :baz].to_enum.with_index(1).each do |elem, i|
  puts "#{i}: #{elem}"
end

आउटपुट:

1: foo
2: bar
3: baz

BTW, मुझे लगता है कि यह केवल 1.9.2 में है।


2
१.. in में यह केवल with_indexकोई 0
परिम

वास्तव में, एक छोटा सा उत्तर भी संभव है, कृपया मुझे नीचे देखें।
ज़ैक जू

50

रूबी के एन्यूमरेटर वर्ग का उपयोग करते हुए, निम्न है।

[:foo, :bar, :baz].each.with_index(1) do |elem, i|
    puts "#{i}: #{elem}"
end

उत्पादन

1: foo
2: bar
3: baz

एरे # प्रत्येक एन्यूमरेटर को लौटाता है, और एन्यूमरेटर को कॉल करके # with_index एक और एन्यूमरेटर लौटाता है, जिसमें एक ब्लॉक पास होता है।


5

1) सबसे सरल कार्य के index+1बजाय स्थानापन्न indexकरना है:

some_array.each_with_index{|item, index| some_func(item, index+1)}

लेकिन शायद वह नहीं है जो आप चाहते हैं।

2) अगली चीज जो आप कर सकते हैं वह है jब्लॉक के भीतर एक अलग सूचकांक को परिभाषित करना और मूल सूचकांक के बजाय इसका उपयोग करना:

some_array.each_with_index{|item, i| j = i + 1; some_func(item, j)}

3) यदि आप अक्सर इस तरह से इंडेक्स का उपयोग करना चाहते हैं, तो एक और तरीका परिभाषित करें:

module Enumerable
  def each_with_index_from_one *args, &pr
    each_with_index(*args){|obj, i| pr.call(obj, i+1)}
  end
end

%w(one two three).each_with_index_from_one{|w, i| puts "#{i}. #{w}"}
# =>
1. one
2. two
3. three


अपडेट करें

यह उत्तर, जो कुछ साल पहले उत्तर दिया गया था, अब अप्रचलित है। आधुनिक रूबी के लिए, ज़ैक जू का जवाब बेहतर काम करेगा।


बुरी बात यह है कि यह सरणी में कोई और अधिक तत्व नहीं होने के बाद भी पुनरावृत्ति करेगा
fl00r

@ fl00r सच में? मेरे उदाहरण में, यह तीन के बाद बंद हो जाता है।
आरा

लेकिन अगर ऑफसेट 2 या 10 है? आपके मामले में ऑफसेट शून्य है। मेरा मतलब है कि आपके (3) में कोई ऑफसेट नहीं है
fl00r

@ fl00r आप सिर्फ +1मेरे कोड को +2या में बदलें +10। साथ ही इसका काम करता है।
आरा

ओएमजी, लेखक ने अपने पद को संपादित किया, इसलिए उन्हें अनुक्रमांकांक की जरूरत है न कि सरणी की।
fl00r

4

यदि some_indexकिसी तरह सार्थक है, तो एक सरणी के बजाय एक हैश का उपयोग करने पर विचार करें।


4

मैं उसमें भाग गया।

मेरा समाधान आवश्यक नहीं सबसे अच्छा है, लेकिन यह सिर्फ मेरे लिए काम करता है।

दृश्य पुनरावृत्ति में:

बस जोड़ें: सूचकांक + 1

यह सब मेरे लिए है, क्योंकि मैं उन इंडेक्स नंबरों के संदर्भ का उपयोग नहीं करता हूं, लेकिन सिर्फ एक सूची में दिखाने के लिए।


3

हाँ तुम कर सकते हो

some_array[offset..-1].each_with_index{|item, index| some_func(item, index) }
some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }
some_array[offset..-1].each_with_index{|item, index| index+=offset; some_func(item, index) }

युपीडी

मुझे यह भी ध्यान रखना चाहिए कि यदि ऑफसेट आपके ऐरे आकार से अधिक है तो यह एक त्रुटि होगी। चूंकि:

some_array[1000,-1] => nil
nil.each_with_index => Error 'undefined method `each_with_index' for nil:NilClass'

हम यहाँ क्या कर सकते हैं:

 (some_array[offset..-1]||[]).each_with_index{|item, index| some_func(item, index) }

या ऑफ़सेट प्रचलित करने के लिए:

 offset = 1000
 some_array[offset..-1].each_with_index{|item, index| some_func(item, index) } if offset <= some_array.size

यह थोड़ा हैकी है

UPD 2

जहाँ तक आपने अपने प्रश्न को अद्यतन किया है और अब आपको ऐरे ऑफ़सेट की आवश्यकता नहीं है, लेकिन इंडेक्स ऑफसेट तो @sawa समाधान आपके लिए ठीक काम करेगा


1

एरियल सही है। इसे संभालने का यह सबसे अच्छा तरीका है, और यह उतना बुरा नहीं है

ary.each_with_index do |a, i|
  puts i + 1
  #other code
end

यह पूरी तरह से स्वीकार्य है, और इसके लिए मैंने जितने भी समाधान देखे हैं उनमें से अधिकांश से बेहतर है। मैंने हमेशा सोचा था कि यह # विषय था ... ओह अच्छी तरह से।


1

एक और दृष्टिकोण का उपयोग करना है map

some_array = [:foo, :bar, :baz]
some_array_plus_offset_index = some_array.each_with_index.map {|item, i| [item, i + 1]}
some_array_plus_offset_index.each{|item, offset_index| some_func(item, offset_index) }

1

यह हर माणिक संस्करण में काम करता है:

%W(one two three).zip(1..3).each do |value, index|
  puts value, index
end

और एक सामान्य सरणी के लिए:

a.zip(1..a.length.each do |value, index|
  puts value, index
end

दूसरे उदाहरण में एक ब्रैकेट गायब है।
वेफरथिन

0
offset = 2
some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.