选自《七周七语言》的 Ruby 部分:
有一个数组,包含 16 个数字。仅用 each 方法打印数组中的内容,一次打印 4 个数字。然后,用可枚举模块的 each_slice 方法重做一遍
我想问如何仅用 each 实现 each_slice 的功能?我的想法很丑陋:
sequence = (1..16)
buffer = []
count = 0
sequence.each do |e|
buffer << e
if buffer.size >= 4
p buffer
buffer = []
end
end
有没有更好的方法呢?
楼主这个是有问题的,如果把 16 改成 15:
sequence = (1..15)
buffer = []
count = 0
sequence.each do |e|
buffer << e
if buffer.size >= 4
p buffer
buffer = []
end
end
# 输出
# [1, 2, 3, 4]
# [5, 6, 7, 8]
# [9, 10, 11, 12]
后面三个没有打出来
我写了一个,但是感觉比较丑陋:
module Enumerable
def i_each_slice(n, &block)
raise "invalid slice size" if n <= 0
i, ary = 0, []
each do |a|
ary << a
i += 1
if i >= n
yield ary
i, ary = 0, []
end
end
yield ary if i > 0
end
end
(1..10).i_each_slice(3) { |a| p a }
# 输出
# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]
# [10]
期待大神们更优雅的解法。
module Enumerable
def i_each_slice(n)
raise "invalid slice size" if n <= 0
result, i = [], 1
self.each do |ele|
index = (i / n.to_f).ceil
result[index].nil? ? result[index] = [ele] : result[index] << ele
i += 1
end
result[1..-1].each { |ele| yield ele }
end
end
['a', 'b', 'c', 'd', 'e', 1, 2, 3, 4, 5].i_each_slice(3) { |i| p i }
# =>
# ["a", "b", "c"]
# ["d", "e", 1]
# [2, 3, 4]
# [5]
还可以再短点不过就要略微影响可读性了
@blacktulip 的解法估计会吓退不少 ruby 初学者 这个不过是个入门级的题,我补充个杀鸡刀版吧
i = 0
(1..16).to_a.each do |n|
i += 1
print i % 4 == 0 ? "#{n}\n" : "#{n},"
end
(0..3).each do |a|
arr = []
(1..4).each do |b|
arr << a * 4 + b
end
puts arr.to_s
end
(1..16).to_a.each_with_index { |n, i| print "#{n}#{(i+1)%4==0 ? "\n" : ","}" }
Only use each here:
(array = (1..16).to_a).each { |n| print "#{n}#{(array.index(n)+1)%4==0 ? "\n" : ","}" }