【问题标题】:Ruby: OOP & two-dim array questionRuby:OOP 和二维数组问题
【发布时间】:2010-12-15 19:19:39
【问题描述】:

我需要创建一个二维数组类。我做了一项工作,但发现我的类只是有一个内部二维数组,并且要访问元素我必须编写一个多余的单词'table':

class Table
  attr_accessor :table
  def initialize(w,h)
    @table = Array.new(h)
    h.times do @table << Array.new(w) 
  end
end

x = Table.new(10,10)
x.table[5][6] = 'example'

等等。这个想法是我想一次只写x[5][6] 来访问元素。据我了解,我必须继承 Array 类,并以某种方式扩展它以充当二维数组。如果我是对的 - 我该怎么做?

【问题讨论】:

    标签: ruby arrays oop inheritance


    【解决方案1】:

    认为这可能就是您正在寻找的。它使用@table 实例变量来跟踪内部数组,但不公开它的访问器。这是定义:

    class Table
    
      def initialize(row_count, column_count)
        @table = Array.new
    
        row_count.times do |index|
          @table[index] = Array.new(column_count)
        end
      end
    
      def []=(row, column, value)
        @table[row][column] = value
      end
    
      def [](row, column = nil)
        if column.nil?
          @table[row]
        else
          @table[row][column]
        end
      end
    
      def inspect
        @table.inspect
      end
    end
    

    下面是你可以使用它的方法:

    t = Table.new(2, 5)
    t[0,0] = 'first'
    t[1,4] = 'last'
    t[0][1] = 'second'
    
    puts t[0,0]
    puts t.inspect
    

    您可能还想看看 Ruby's enumerable module 而不是继承 Array。

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      您有什么特别的原因想要编写自己的数组类吗?默认情况下,您可以通过提供第二个参数来告诉数组用什么填充新元素:

      >> a = Array.new(10, [])
      => [[], [], [], [], [], [], [], [], [], []]
      

      编辑:显然,这种方式会使用对传递对象的引用填充数组,因此一旦您执行a[0][0] = "asd",包含数组的每个第一个元素都会更改。不酷。

      >> a[0][0] = "asd"
      => "asd"
      >> a
      => [["asd"], ["asd"], ["asd"], ["asd"], ["asd"], ["asd"], ["asd"], ["asd"], ["asd"], ["asd"]]
      

      要使每个包含的数组都是唯一的,请使用第三种语法,并给它一个每次执行的块 - 块的结果将用于填充数组:

      >> b = Array.new(10) { [] }
      => [[], [], [], [], [], [], [], [], [], []]
      >> b[0][0] = "asd"
      => "asd"
      >> b
      => [["asd"], [], [], [], [], [], [], [], [], []]
      

      此外,由于 ruby​​ 数组的工作方式,甚至不需要定义 y 轴大小:

      >> a = Array.new(5)
      => [nil, nil, nil, nil, nil]
      >> a[10]
      => nil
      >> a[10] = "asd"
      => "asd"
      >> a
      => [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "asd"]
      

      当您在索引中放入大于当前大小的内容时,数组会自动扩展。因此,只需创建一个包含 10 个空数组的数组,就可以使用 10*n 大小的数组了。

      【讨论】:

      • 是的,我真的很想创建一个类来将它的内部路由(即方法)与我现在正在研究的实际算法的逻辑分开。感谢数组自动调整大小!不知道
      猜你喜欢
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      • 2019-08-08
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      相关资源
      最近更新 更多