Best Way to Split Arrays into Multiple Small Arrays in Ruby

Best way to split arrays into multiple small arrays in ruby

You're looking for Enumerable#partition:

x = [1, 2, 3, "a", "b", 4]
numbers, not_numbers = x.partition{|item| item.kind_of?(Fixnum)}
# => [[1, 2, 3, 4], ["a", "b"]]

How to split (chunk) a Ruby array into parts of X elements?

Take a look at Enumerable#each_slice:

foo.each_slice(3).to_a
#=> [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"], ["10"]]

Refactor ruby code to split array into two small arrays

Sounds like a job for partition:

partition { |obj| block } → [ true_array, false_array ]
partition → an_enumerator

Returns two arrays, the first containing the elements of enum for which the block evaluates to true, the second containing the rest.

This should do the job:

@open, @closed = @posts.partition { |p| p.status == 'Open' }

How to split a Ruby array into a certain number of smaller arrays?

If you're using Rails (you don't say) you could use in_groups.

%w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
["1", "2", "3", "4"]
["5", "6", "7", nil]
["8", "9", "10", nil]

http://api.rubyonrails.org/classes/Array.html#method-i-in_groups

Or, if not Rails, just take the source for that method...

How to split a Ruby array into subarrays of unequal size using a delimiter

Enumerable#slice_before does this exact thing:

arr = [0, 1, 1, 2, 3, 1, 0, 0, 1]
p arr.slice_before(0).to_a
# => [[0, 1, 1, 2, 3, 1], [0], [0, 1]]

See it on repl.it: https://repl.it/FBhg

How do I split an array into smaller arrays bsaed on a condition?

One more way to skin a cat

def contains_vowel(v) 
v.count("aeiou") > 0
end
def split_by_substring_with_vowels(arr)
arr.chunk_while do |before,after|
!contains_vowel(before) & !contains_vowel(after)
end.to_a
end
split_by_substring_with_vowels(arr)
#=> [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]

What it does:

  • passes each consecutive 2 elements
  • splits when either of them contain vowels

Example with your other Array

arr = ["1)", "dwr", "lyn,", "18,", "bbe"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe"]]

Further example: (if you want vowel containing elements in succession to stay in the same group)

def split_by_substring_with_vowels(arr)
arr.chunk_while do |before,after|
v_before,v_after = contains_vowel(before),contains_vowel(after)
(!v_before & !v_after) ^ (v_before & v_after)
end.to_a
end

arr = ["1)", "dwr", "lyn,", "18,", "bbe", "re", "rr", "aa", "ee"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe", "re"], ["rr"], ["aa", "ee"]]

This checks if before and after are both not vowels Or if they both are vowels

Dividing elements of a ruby array into an exact number of (nearly) equal-sized sub-arrays

You're looking for Enumerable#each_slice

a = [0, 1, 2, 3, 4, 5, 6, 7]
a.each_slice(3) # => #<Enumerator: [0, 1, 2, 3, 4, 5, 6, 7]:each_slice(3)>
a.each_slice(3).to_a # => [[0, 1, 2], [3, 4, 5], [6, 7]]

Split array into sub-arrays based on value

I tried golfing it a bit, still not a single method though:

(1..9).chunk{|i|i%3==0}.reject{|sep,ans| sep}.map{|sep,ans| ans}

Or faster:

(1..9).chunk{|i|i%3==0 || nil}.map{|sep,ans| sep&&ans}.compact

Also, Enumerable#chunk seems to be Ruby 1.9+, but it is very close to what you want.

For example, the raw output would be:

(1..9).chunk{ |i|i%3==0 }.to_a                                       
=> [[false, [1, 2]], [true, [3]], [false, [4, 5]], [true, [6]], [false, [7, 8]], [true, [9]]]

(The to_a is to make irb print something nice, since chunk gives you an enumerator rather than an Array)


Edit: Note that the above elegant solutions are 2-3x slower than the fastest implementation:

module Enumerable
def split_by
result = [a=[]]
each{ |o| yield(o) ? (result << a=[]) : (a << o) }
result.pop if a.empty?
result
end
end

Need to split arrays to sub arrays of specified size in Ruby

arr.each_slice(3).to_a

each_slice returns an Enumerable, so if that's enough for you, you don't need to call to_a.

In 1.8.6 you need to do:

require 'enumerator'
arr.enum_for(:each_slice, 3).to_a

If you just need to iterate, you can simply do:

arr.each_slice(3) do |x,y,z|
puts(x+y+z)
end


Related Topics



Leave a reply



Submit