简体   繁体   中英

Multidimensional ruby array: Is it possible to define the []-operator with more than one argument?

I want to implement a table datastructure. Maybe you can recommend a better alternative, but as Ruby doesn't provide built-in support for multidimensional arrays, the nearest solution is using a Hash and an Array as index

pseudoTable = Hash.new
pseudoTable[[0,"id"]] = 23
pseudoTable[[0,"name"]] = "Hans"

Now I tried the following

class MyTable
  attr_accessor :id, :table_hash
  def [](a,b)
    @table_hash[[a,b]]
  end
end

So, isn't it possible in Ruby to give two arguments to def []() ?

If not, can you recommend another approach (a built-in datastructure than Hash, etc. better suited) to implement a table capable of dynamic extension and bonus points for being sequentially iterable?

Is this the behavior you're looking for?

class MyTable
  def initialize()
    @table = Hash.new
  end

  def [](a, b)
    return nil if @table[a].nil?
    @table[a][b]
  end

  def []=(a, b, c)
    @table[a] ||= {}
    @table[a][b] = c
  end
end

usage:

2.4.1 :038 > a = MyTable.new
 => #<MyTable:0x007faf6f9161c8 @table={}>
2.4.1 :039 > a[0,0]
 => nil
2.4.1 :040 > a[0,0] = 1
 => 1
2.4.1 :041 > a[0,0]
 => 1

I'm pretty confident there are better ways to do this, and this solution might contain some bugs, but hopefully it demonstrates how to define and use multi-argument [] and []= methods.

You can try to use ruby-numo library

apt install -y git ruby gcc ruby-dev rake make
gem install specific_install
gem specific_install https://github.com/ruby-numo/narray.git

irb

arr = Numo::Narray[[1], [1, 2], [1, 2, 3]]

 => Numo::Int32#shape=[3,3]
[[1, 0, 0],
 [1, 2, 0],
 [1, 2, 3]]

arr[0, 0]
 => 1

arr[0, 1]
 => 0

arr[0, 2]
 => 0

arr[0, 3]
IndexError: index=3 out of shape[1]=3    

You can learn more detailed documentation there

What you did would work fine, the trouble is that @table_hash is not recognised as a hash. You need to initialize it as such.

class MyTable
  attr_accessor :id, :table_hash

  def initialize(*args)
    @table_hash = Hash.new
    super
  end

  def [](a,b)
    @table_hash[[a,b]]
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM