Guest User

Untitled

a guest
Apr 22nd, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.32 KB | None | 0 0
  1. class MArray # for working with multidimensional data
  2. attr_reader :sizes
  3.  
  4. def initialize(*args) # args = [size for each dimension]
  5. @sizes = args
  6. @data = Array.new(@sizes.product)
  7. @data.each_with_index { |x, i| @data[i] = yield i } if block_given? # to support block initialisation
  8. end
  9.  
  10. def [](*args)
  11. raise ArgumentError if args.size != self.dimension
  12. @data[self.get_offset(*args)]
  13. end
  14.  
  15. def []=(*args)
  16. raise ArgumentError if args.size != self.dimension + 1
  17. value = args.pop
  18. @data[self.get_offset(*args)] = value
  19. end
  20.  
  21. def dimension
  22. @dimension ||= @sizes.size
  23. end
  24.  
  25. def get_offset(*args)
  26. offset = 0
  27. args.each_with_index do |a, i|
  28. raise IndexError unless a < sizes[i]
  29. offset += a * self.sizes.first(i).product # product of an empty array is 1
  30. end
  31. offset
  32. end
  33.  
  34. def each
  35. @data.each { |v| yield v } # avoiding Proc, conversion is slow!
  36. end
  37.  
  38. include Enumerable
  39.  
  40. def flatten
  41. @data.dup
  42. end
  43.  
  44. # TODO: methods to reduce dimensions (by 1 or by n - 1)
  45. def reduce(d, r) # d is the dimension (index in self.sizes)
  46. # r is which 'hyperrow' is selected in the dimension being reduced
  47. end
  48. # TODO: unwind: returns an array of arrays of arrays of arrays of arrays ... of arrays.
  49. end
Add Comment
Please, Sign In to add comment