【问题标题】:What does * mean at the beginning of a range? [duplicate]* 在范围的开头是什么意思? [复制]
【发布时间】:2019-04-28 08:29:50
【问题描述】:

抱歉这个菜鸟问题,但是这个星号在一个范围的开头是什么意思?

class Matrix
  def initialize(matrix_string)
    @matrix = matrix_string.split("\n").map do |row|
        row.split.map(&:to_i)
    end
    @rows = rows.length
    @cols = columns.length
  end

  def rows
    @matrix
  end

  def columns
    @matrix.transpose
  end

  # --->>***
  def saddle_points
    [*0...@rows].product([*0...@cols]).select do |coords|
        saddle_point?(*coords)
  end
  # ***<----
end

private
  def   saddle_point?(row, col)
    (@matrix[row][col] == rows[row].max) && 
    (@matrix[row][col] == columns[col].min)
  end
end

【问题讨论】:

标签: arrays ruby range


【解决方案1】:

正如in the documentation所说:

您可以使用 *(或 splat)运算符将 Array 转换为参数列表:

arguments = [1, 2, 3]
my_method(*arguments)

Range 也可以这样做:

arguments = 1..3
my_method(*arguments) # essentially the same as my_method(1, 2, 3)

还允许在数组声明内的范围之前使用 splat 运算符将Range 隐式转换为Array

[*1..3]
#⇒ [1, 2, 3]

【讨论】:

    【解决方案2】:

    * 通过“喷溅”其内容并将其转换为数组来解压数组。

    【讨论】:

      【解决方案3】:

      正如其他答案所述,* 运算符用于将数组转换为参数列表。

      但是如果对象不是一个数组怎么办,就像你的情况一样?然后 Ruby 将在对象上调用 #to_a(如果已定义),并使用返回的数组代替。否则,使用对象本身。

      这是对象既不是数组也没有定义#to_a的情况:

      x = *4 # => [4]
      

      如果对象定义了#to_a,就会被调用并使用,如Range的情况:

      x = *0..1 # => [0, 1]
      

      为了证明这一点,我们可以预先添加一个模块来跟踪对 #to_a 的调用:

      module Trace
        def to_a
          puts "#to_a called"
          super
        end
      end
      
      Range.prepend(Trace)
      
      x = *0..1
      # prints "#to_a called"
      # => [0, 1]
      

      请注意,如果您的对象已经是 Array 类型,Ruby 将不会调用 #to_a

      我们也可以在自定义类型上使用它:

      class Foo
        def to_a
          [1, 2, 3]
        end
      end
      
      x = *Foo.new # => [1, 2, 3]
      

      顺便说一句,Ruby 的nil 也实现了#to_a。这允许我们将nil 作为参数传递,就好像什么都没传递一样,因为nil.to_a 返回[]

      def count(*args)
        args.count
      end
      
      count # => 0
      count(*0..1) # => 2
      count(*nil) # => 0
      

      当您有一个可能是 nil 的变量并将其传递给具有默认值的方法时,这会很有用:

      def say_hi(name = "Jane")
        puts "Hi, #{name}"
      end
      
      name = nil
      say_hi(*name) # prints "Hi, Jane"
      

      但是如果我们删除NilClass#to_a:

      NilClass.undef_method(:to_a)
      
      say_hi(*name) # prints "Hi, "
      

      【讨论】:

        猜你喜欢
        • 2011-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-27
        • 2015-07-15
        • 2018-07-17
        相关资源
        最近更新 更多