Looping through an array with step
Solution 1
Ranges have a step
method which you can use to skip through the indexes:
(0..array.length - 1).step(2).each do |index|
value_you_care_about = array[index]
end
Or if you are comfortable using ...
with ranges the following is a bit more concise:
(0...array.length).step(2).each do |index|
value_you_care_about = array[index]
end
Solution 2
array.each_slice(n) do |e, *_|
value_i_care_about = e
end
Solution 3
Just use step() method from Range class which returns an enumerator
(1..10).step(2) {|x| puts x}
Solution 4
We can iterate while skipping over a range of numbers on every iteration e.g.:
1.step(10, 2) { |i| print "#{i} "}
http://www.skorks.com/2009/09/a-wealth-of-ruby-loops-and-iterators/
So something like:
array.step(n) do |element|
# process element
end
Related videos on Youtube
baash05
Under the hood, we all want to know more. We are here to learn through our life, to be more than when we started out. We joined StackOverflow to learn and to share. Who am I? About me? I am a father of two amazing children: bright happy and filled with energy. I am a husband, of one amazing woman. I say I like to run, but I don't do it, I say I love to code, and I do it almost as often as I can. I used to do WingChun, and in some ways it defines who I turned into. A man who loves simple logic. Low level where and when I can. I like to find the rules and then twist them about, bending but never break them.
Updated on November 01, 2020Comments
-
baash05 over 3 years
I want to look at every n-th elements in an array. In C++, I'd do this:
for(int x = 0; x<cx; x+=n){ value_i_care_about = array[x]; //do something with the value I care about. }
I want to do the same in Ruby, but can't find a way to "step". A
while
loop could do the job, but I find it distasteful using it for a known size, and expect there to be a better (more Ruby) way of doing this.-
baash05 over 11 yearsNothing about the step could be found :) each.. or for loop is easy to find.. I want to do every 5th or 10th or 9th element in the array
-
Mischa over 11 yearsBenjamin's answer is incorrect. You should look at Levi's or David's answer.
-
Mischa over 11 yearsYes, it makes sense that
1.step(3, 2)
gives 1 and 3. In this code the step is 2, so the second element gets skipped. Which leaves you with 1 and 3. -
baash05 over 11 yearsYeah I see how it works now. Thanks all.
-
mrbrdo over 11 yearsBy the way, this has nothing to do with Rails, it's a Ruby question.
-
-
baash05 over 11 yearsYou missed the bit about the step. That was the important bit.
-
bdeonovic over 11 yearsJust feeling a bit under the weather tonight =D
-
Mischa over 11 yearsThis doesn't work.
Array
doesn't have astep
method, so you will get "Undefined method for step".1.step(10,2)
does work, but that doesn't iterate over an array. Levi has the correct answer. -
baash05 over 11 yearshad to vote you down... if n is 1000 then and I've got 10000 elements I've just done 10000 if's I didn't need to to get 10 elements.
-
baash05 over 11 yearsYeah.. but in Ben's defence.. it was enough to figure it out. And Levi's doesn't iterate over the array either. Both excellent answers.
-
doesterr over 11 yearsI was just wondering why it got downvoted.. thanks for letting me know
-
doesterr over 11 yearsOf course you're absolutely right with that. The negative impact gets larger, the bigger your step size is. If you're as curious about it as I was just now, see the significant benchmark results in this gist: gist.github.com/3936015
-
baash05 over 11 yearsexcellent search dave. Anytime a compare is in the loop it's run each time.. if you can get if's out of your loop it runs faster. I like to watch my cycles and let the .... take care of them selves.
-
doesterr over 11 yearsthen, I'll just replace my
if
s withunless
... jk ;) -
244an over 10 yearsYou can use
(0...array.length)
instead of(0..array.length - 1)
-
baash05 over 9 yearsnice. Not in love with the idea of creating a range of a million where an int would do the job in c++.. but cool
-
Mark Thomas over 8 yearsUm, maybe, but in this case completely unnecessary. Just use the block form of select:
[1, 2, 3, 4, 5, 6, 7].select(&:odd?)