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
Ruby: Put Request with JSON Body
Best Way to Monitor for Completion of a Sidekiq Job
Gem Dependencies Versions Meaning
How to Add a Method to the Global Scope in Ruby
Heroku Gem Not Working with Rvm
Declaring Instance Variables Iterating Over a Hash!
How to Validate Associated Model Id
Getting a Dns Txt Record in Ruby
How to Check If a Folder Exists in Chef
Package Ruby to a Standalone MAC Os X Application
Generate Ruby Classes from Xsd
Installing Gem Fails with Permissions Error
Rails Activeadmin: Showing Table of a Related Resource in the Same View
Loop Through Activerecord::Associations::Collectionproxy with Each
Context Aware Authorization Using Cancan
Restarting Unicorn with Usr2 Doesn't Seem to Reload Production.Rb Settings