我试着清理我的代码.第一个版本使用each_with_index.在第二个版本中,我试图用Enumerable.inject_with_index-construct我在这里找到的代码压缩代码.
它现在有效,但在我看来像第一个代码一样模糊.添加更糟糕我不明白元素周围的括号,索引
.. .inject(groups) do |group_container, (element,index)|
Run Code Online (Sandbox Code Playgroud)
但他们是必要的
class Array
# splits as good as possible to groups of same size
# elements are sorted. I.e. low elements go to the first group,
# and high elements to the last group
#
# the default for number_of_groups is 4
# because the intended use case is
# splitting statistic data in 4 quartiles
#
# a = [1, 8, 7, 5, 4, 2, 3, 8]
# a.sorted_in_groups(3) # => [[1, 2, 3], [4, 5, 7], [8, 8]]
#
# b = [[7, 8, 9], [4, 5, 7], [2, 8]]
# b.sorted_in_groups(2) {|sub_ary| sub_ary.sum } # => [ [[2, 8], [4, 5, 7]], [[7, 8, 9]] ]
def sorted_in_groups(number_of_groups = 4)
groups = Array.new(number_of_groups) { Array.new }
return groups if size == 0
average_group_size = size.to_f / number_of_groups.to_f
sorted = block_given? ? self.sort_by {|element| yield(element)} : self.sort
sorted.each_with_index do |element, index|
group_number = (index.to_f / average_group_size).floor
groups[group_number] << element
end
groups
end
end
Run Code Online (Sandbox Code Playgroud)
class Array
def sorted_in_groups(number_of_groups = 4)
groups = Array.new(number_of_groups) { Array.new }
return groups if size == 0
average_group_size = size.to_f / number_of_groups.to_f
sorted = block_given? ? self.sort_by {|element| yield(element)} : self.sort
sorted.each_with_index.inject(groups) do |group_container, (element,index)|
group_number = (index.to_f / average_group_size).floor
group_container[group_number] << element
group_container
end
end
end
Run Code Online (Sandbox Code Playgroud)
Ser*_*sev 27
这些括号有什么用?
这是红宝石的一个非常好的功能.我把它称为"解构数组赋值",但它也可能有正式名称.
这是它的工作原理.假设你有一个阵列
arr = [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
然后将此数组分配给名称列表,如下所示:
a, b, c = arr
a # => 1
b # => 2
c # => 3
Run Code Online (Sandbox Code Playgroud)
你看,阵列被"解构"成它的各个元素.现在,到了each_with_index.如你所知,它就像一个普通的each,但也返回一个索引.inject并不关心所有这一切,它需要输入元素并将它们传递给它的块.如果input元素是一个数组(elem/index pair from each_with_index),那么我们可以在块体中将它分开
sorted.each_with_index.inject(groups) do |group_container, pair|
element, index = pair
# or
# element = pair[0]
# index = pair[1]
# rest of your code
end
Run Code Online (Sandbox Code Playgroud)
或者在块签名中对该数组进行解构.括号中有必要给ruby一个暗示,这是一个需要分成几个参数的单个参数.
希望这可以帮助.
lines = %(a b c)
indexes = lines.each_with_index.inject([]) do |acc, (el, ind)|
acc << ind - 1 if el == "b"
acc
end
indexes # => [0]
Run Code Online (Sandbox Code Playgroud)