Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class MArray # for working with multidimensional data
- attr_reader :sizes
- def initialize(*args) # args = [size for each dimension]
- @sizes = args
- @data = Array.new(@sizes.product)
- @data.each_with_index { |x, i| @data[i] = yield i } if block_given? # to support block initialisation
- end
- def [](*args)
- raise ArgumentError if args.size != self.dimension
- @data[self.get_offset(*args)]
- end
- def []=(*args)
- raise ArgumentError if args.size != self.dimension + 1
- value = args.pop
- @data[self.get_offset(*args)] = value
- end
- def dimension
- @dimension ||= @sizes.size
- end
- def get_offset(*args)
- offset = 0
- args.each_with_index do |a, i|
- raise IndexError unless a < sizes[i]
- offset += a * self.sizes.first(i).product # product of an empty array is 1
- end
- offset
- end
- def each
- @data.each { |v| yield v } # avoiding Proc, conversion is slow!
- end
- include Enumerable
- def flatten
- @data.dup
- end
- # TODO: methods to reduce dimensions (by 1 or by n - 1)
- def reduce(d, r) # d is the dimension (index in self.sizes)
- # r is which 'hyperrow' is selected in the dimension being reduced
- end
- # TODO: unwind: returns an array of arrays of arrays of arrays of arrays ... of arrays.
- end
Add Comment
Please, Sign In to add comment