Ruby multidimensional array

前端 未结 11 1476
春和景丽
春和景丽 2020-11-28 09:30

Maybe it\'s just my lack of abilities to find stuff here that is the problem, but I can\'t find anything about how to create multidimensional arrays in Ruby.

Could s

11条回答
  •  南笙
    南笙 (楼主)
    2020-11-28 09:52

    Perhaps you can simulate your multidimensional Array with a Hash. The Hash-key can by any Ruby object, so you could also take an array.

    Example:

    marray = {}
    p marray[[1,2]]   #-> nil
    marray[[1,2]] = :a
    p marray[[1,2]]   #-> :a
    

    Based on this idea you could define a new class.

    Just a quick scenario:

    =begin rdoc
    Define a multidimensional array.
    
    The keys must be Fixnum.
    
    The following features from Array are not supported:
    * negative keys (Like Array[-1])
    * No methods <<, each, ...
    =end
    class MArray
      INFINITY = Float::INFINITY
    =begin rdoc
    =end
      def initialize(dimensions=2, *limits)
        @dimensions = dimensions
        raise ArgumentError if limits.size > dimensions
        @limits = []
        0.upto(@dimensions-1){|i|
          @limits << (limits[i] || INFINITY)
        }
        @content = {}
      end
      attr_reader :dimensions
      attr_reader :limits
    =begin rdoc
    =end
      def checkkeys(keys)
        raise ArgumentError, "Additional key values for %i-dimensional Array" % @dimensions if keys.size > @dimensions
        raise ArgumentError, "Missing key values for %i-dimensional Array" % @dimensions if keys.size != @dimensions
        raise ArgumentError, "No keys given" if keys.size == 0
        keys.each_with_index{|key,i|
          raise ArgumentError, "Exceeded limit for %i dimension" % (i+1) if key > @limits[i]
          raise ArgumentError, "Only positive numbers allowed" if key < 1
    
        }
      end
      def[]=(*keys)
        data = keys.pop
        checkkeys(keys)
        @content[keys] = data
      end
      def[](*keys)
        checkkeys(keys)
        @content[keys]
      end
    end
    

    This can be used as:

    arr = MArray.new()
    arr[1,1] = 3
    arr[2,2] = 3
    

    If you need a predefined matrix 2x2 you can use it as:

    arr = MArray.new(2,2,2)
    arr[1,1] = 3
    arr[2,2] = 3
    #~ arr[3,2] = 3  #Exceeded limit for 1 dimension (ArgumentError)
    

    I could imagine how to handle commands like << or each in a two-dimensional array, but not in multidimensional ones.

提交回复
热议问题