Ruby Array Each_Slice_With_Index

Ruby array each_slice_with_index?

Like most iterator methods, each_slice returns an enumerable when called without a block since ruby 1.8.7+, which you can then call further enumerable methods on. So you can do:

arr.each_slice(2).with_index { |(a, b), i| puts "#{i} - #{a}, #{b}" }

Ruby .each_slice with condition even and odd indexes of an array

newArrayOne, newArrayTwo = array.partition.with_index { |_,i| i.even? }

Ruby each_slice into sub arrays and set default element values if last sub-array is different size to other sub-arrays

#tap into the resulting array and #fill the last element with the necessary number of false elements:

array = ["1", "b", "0", "7", "9", "2", "a", "a", "5", "7"]
array
.each_slice(3)
.to_a
.tap { |a| a.last.fill(false, a.last.length, 3 - a.last.length) }

How to return a part of an array in Ruby?

Yes, Ruby has very similar array-slicing syntax to Python. Here is the ri documentation for the array index method:

--------------------------------------------------------------- Array#[]
array[index] -> obj or nil
array[start, length] -> an_array or nil
array[range] -> an_array or nil
array.slice(index) -> obj or nil
array.slice(start, length) -> an_array or nil
array.slice(range) -> an_array or nil
------------------------------------------------------------------------
Element Reference---Returns the element at index, or returns a
subarray starting at start and continuing for length elements, or
returns a subarray specified by range. Negative indices count
backward from the end of the array (-1 is the last element).
Returns nil if the index (or starting index) are out of range.

a = [ "a", "b", "c", "d", "e" ]
a[2] + a[0] + a[1] #=> "cab"
a[6] #=> nil
a[1, 2] #=> [ "b", "c" ]
a[1..3] #=> [ "b", "c", "d" ]
a[4..7] #=> [ "e" ]
a[6..10] #=> nil
a[-3, 3] #=> [ "c", "d", "e" ]
# special cases
a[5] #=> nil
a[6, 1] #=> nil
a[5, 1] #=> []
a[5..10] #=> []

How slice an array while avoiding duplicate values in each slice?

a = [1,2,3,3,3,3,3,3,3,3,3,4,5,6,6,7,8,9,10,11]

You can test if slices are "unique" by:

a.each_slice(2).all?{|x| x == x.uniq}

So now you just shuffle until you get what you want:

a.shuffle! until a.each_slice(2).all?{|x| x == x.uniq}

The easiest way to avoid an infinite loop is with timeout:

require 'timeout'
# raise an error if it takes more than 1 second
timeout(1){ a.shuffle! until a.each_slice(3).all?{|x| x == x.uniq} }

Rails each_slice displaying array at bottom of page

The problematic part is = group.each do |post| since each returns the array itself as well in addition to running the loop. And since you have an = sign before it so the = in the view would also render the returned output of the group.each statement. You may want to use - as - group.each do |post| as it will render the output of group.each.

`Array#each_slice`, leaving remainders at the beginning

Though one might reverse an array thrice, there is more efficient way to achieve a goal:

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
a = arr.dup # not to modify it inplace
[a.shift(a.size % 3)] + a.each_slice(3).to_a
#⇒ [[1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

BTW, arr.each_slice(3) returns an enumerator, not an array as you posted in the question.

upd or, as suggested by Cary Swoveland, to void dup:

n = a.size % 3
[a[0...n]] + a[n..-1].each_slice(3).to_a

upd getting rid of dup by @sawa:

[a.first(a.size % 3)] + a.drop(a.size % 3).each_slice(3).to_a

upd just out of curiosity (assuming an input has no nil elements):

([nil] * (3 - a.size % 3) + a).each_slice(3).to_a.tap do |a|
a.unshift(a.shift.compact!)
end

the above might be safely run on original array, it does not modify it inplace.

UPD2 as pointed out by Stefan in comments, any of the above will produce an initial empty slice if the array is divisible by 3. So, the proper solution (and, the fastest, btw) should look like:

(arr.size % 3).zero? ? arr.each_slice(3).to_a : ANY_OF_THE_ABOVE

Iterate elements in array, except the first two, but also using each_slice

Your code

each_slice returns an Enumerable, but you define your method for Array. Just define it for Enumerable :

module Enumerable
def each_after(n)
each_with_index do |elem, i|
yield elem if i >= n
end
end
end

You can then use

array.each_slice(2).each_after(1) do |m, v|
puts "#{m}, #{v}"
end

Note that you need to drop 1 element (a 2-element Array).

Without changing your method, you could also use to_a before your Array method :

array.each_slice(2).to_a.each_after(1) do |m, v|
puts "#{m}, #{v}"
end

Alternative

Just use drop before each_slice :

["month", "value", "january", "30%", "february", "40%"].drop(2).each_slice(2).to_a
#=> [["january", "30%"], ["february", "40%"]]


Related Topics



Leave a reply



Submit