Ruby注入了索引和括号

ovh*_*aag 19 ruby

我试着清理我的代码.第一个版本使用each_with_index.在第二个版本中,我试图用Enumerable.inject_with_index-construct我在这里找到的代码压缩代码.

它现在有效,但在我看来像第一个代码一样模糊.添加更糟糕我不明白元素周围的括号,索引

.. .inject(groups) do |group_container, (element,index)|
Run Code Online (Sandbox Code Playgroud)

但他们是必要的

  • 这些括号有什么用?
  • 如何使代码清晰可读?

第一版 - 带"each_with_index"

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一个暗示,这是一个需要分成几个参数的单个参数.

希望这可以帮助.


Dor*_*ian 8

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)