Brackets [...]方法以数组作为参数

时间:2016-12-28 16:26:13

标签: arrays ruby hash

我在another answer中读到[]方法可以将数组作为参数。

链接帖子中给出的两个示例都没有说明使用此技术的实际结果。

我尝试了一些也没有提供太多信息的例子:

[11] pry(main)> a = %w( foo bar baz )
=> ["foo", "bar", "baz"]
[12] pry(main)> a[[1,2]]
TypeError: no implicit conversion of Array into Integer
from (pry):11:in '[]'
[13] pry(main)> a[['foo', 'bar']]
TypeError: no implicit conversion of Array into Integer
from (pry):12:in '[]'
[14] pry(main)> b = { foo: 42, bar: "dolphins", baz: "towels" }
=> {:foo=>42, :bar=>"dolphins", :baz=>"towels"}
[15] pry(main)> b[[:foo, :bar]]
=> nil
[16] pry(main)> b[["dolphins"]]
=> nil

[]将数组作为参数是什么意思?这种技术使用的背景是什么?

非常感谢一些可运行的示例,这些示例将帮助我理解为什么我的所有示例都返回nil或错误。

5 个答案:

答案 0 :(得分:1)

[]只是另一种方法。

与其他语言不同,Ruby运算符只是方法,任何方法都可以将任何对象作为参数,包括数组。

class A
  def [](key)
    p key
  end
  def example(key)
    p key
  end 
end

然后

a = A.new

a[1] # => 1
a[[1, 2, 3]] # => [1, 2, 3]

a.[](1) # => 1
a.[]([1, 2, 3]) # => [1, 2, 3]

a.example(1) # => 1
a.example([1, 2, 3]) # =>  [1, 2, 3]

a.send(:'[]', 1) # => 1
a.send(:'[]', [1, 2, 3]) # => [1, 2, 3]

a.send(:example, 1) # => 1
a.send(:example, [1, 2, 3]) # => [1, 2, 3]

Ruby中的其他运算符方法是

  • def []=(key, value)
  • def +(other)
  • def -(other)
  • def *(other)
  • def /(other)
  • def %(other)
  • def &(other)
  • def |(other)
  • def ^(other)
  • def ~(other)
  • def ==(other)
  • def ===(other)
  • def <=>(other)
  • def <=(other)
  • def >=(other)
  • def <(other)
  • def >(other)
  • def <<(other)
  • def !
  • def ~
  • def +@+a
  • 一样
  • def -@-a
  • 一样

答案 1 :(得分:0)

如果是散列,则可以将密钥设为数组。所以你可以通过它查找。在您的示例中,您尝试在b上执行类似的操作,但它没有与您的数组参数匹配的键。

foo = {['bar'] => 'value'}
foo[['bar']]
   => "value"

答案 2 :(得分:0)

关闭@Jared的答案,重要的一点是哈希的键可以是一个数组。另一种说法是散列的[]方法可以将数组作为参数。

另外从另一个角度来看:数组的索引不能是数组。另一种说法是数组的[]方法不能将数组作为参数。

现在上面的例子很有意义。

[11] pry(main)> a = %w( foo bar baz )
=> ["foo", "bar", "baz"]
[12] pry(main)> a[[1,2]]
TypeError: no implicit conversion of Array into Integer
from (pry):11:in `[]'
[13] pry(main)> a[['foo', 'bar']]
TypeError: no implicit conversion of Array into Integer
from (pry):12:in `[]'

如上所述,这是一个错误,因为数组将整数作为索引而不是数组。

[14] pry(main)> b = { foo: 42, bar: "dolphins", baz: "towels" }
=> {:foo=>42, :bar=>"dolphins", :baz=>"towels"}
[15] pry(main)> b[[:foo, :bar]]
=> nil
[16] pry(main)> b[["dolphins"]]
=> nil

这不是错误,因为哈希的键可以是数组。但是,键[:foo, :bar]["dolphins"]尚未定义,因此返回nil

另一个更具说明性的例子是:

[1] pry(main)> h = { foo: 42, bar: "cats" }
=> {:foo=>42, :bar=>"cats"}
[2] pry(main)> h[[:foo, :bar]]
=> nil
[3] pry(main)> h[[:foo, :bar]] = "dogs"
=> "dogs"
[4] pry(main)> h[[:foo, :bar]]
=> "dogs"
[5] pry(main)> h
=> {:foo=>42, :bar=>"cats", [:foo, :bar]=>"dogs"}

[3]中,我们将哈希[:foo, :bar]中的键h定义为"dogs",以便在[4]中返回返回的内容,并在{ {1}}我们可以在哈希中看到键值对。

答案 3 :(得分:0)

Receiver是一个哈希

Receiver可能是一个Hash,其中Arrays为键

Splat参数

你也可以拆开阵列:

a = %w( foo bar baz )
a[*[1,2]]
#=> ["bar", "baz"]

此语法相当于a[1,2],表示take 2 values beginning at index 1

定义自定义类和[]方法

您还可以定义自定义类和[]方法,接受任何对象:

class MyObject
  def self.[](argument)
    "MyObject[] has been called with an #{argument.class}"
    # do something with argument
  end
end

puts MyObject[[1,2,3]]    #=> MyObject[] has been called with an Array
puts MyObject[Object.new] #=> MyObject[] has been called with an Object

答案 4 :(得分:0)

这是红宝石。 Whatever#[]只是一种方法。考虑Hash类,定义类方法Hash#[]。它用于从2个大小的数组数组中构造Hash实例:

Hash[[[:foo, 42]]]
#⇒ { :foo => 42 }

此外,Hash本身可能有数组作为键:

hash = { [1, 2, 3] => :foo }
hash[[1, 2, 3]]
#⇒ :foo