| 赞 | 72 |
| VIP | |
| 好人卡 | |
| 积分 | 23 |
| 经验 | |
| 最后登录 | 2022-3-9 |
| 在线时间 | 4033 小时 |
…あたしは天
- 梦石
- 0
- 星屑
- 2308
- 在线时间
- 4033 小时
- 注册时间
- 2010-10-4
- 回帖
- 10548
 
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 taroxd 于 2014-8-15 12:16 编辑
@寒冷魔王 你不是要多维数组吗,写给你就是了
@myownroc 你是不是也说过要啥多维数组来着
@余烬之中 我又来卖萌了
虽然下面这段代码相当没用,只是给Ruby数组加个包装而已。(不然我也不会发在水区)
既然写出来了,就干脆发出来玩玩吧。
代码
[pre lang="ruby" line="1"]
class Array
def self.dimension(d = 2)
d == 1 ? [] : MultiDimensional.new(d)
end
end
class Array::MultiDimensional
def self.from_data(dimension, data)
new(dimension).tap {|a| a.instance_variable_set(:@data, data) }
end
include Enumerable
attr_reader :dimension
def initialize(dimension)
@dimension = dimension
@data = []
end
def [](first, *indice)
return row(first) if indice.empty?
row(first)[*indice]
end
alias slice []
def slice!(first, *indice)
row(first).slice!(*indice)
end
def []=(first, *indice, value)
row(first)[*indice] = value
end
def each(&block)
return to_enum(__method__) unless block
@data.each {|a| a.each(&block) if a }
self
end
def each_index
return to_enum(__method__) unless block_given?
@data.each_with_index {|a, i| a.each_index {|*j| yield i, *j } if a }
self
end
def each_with_index
return to_enum(__method__) unless block_given?
@data.each_with_index do |a, i|
a.each_with_index {|e, *j| yield e, i, *j } if a
end
self
end
def each_row
return to_enum(__method__) unless block_given?
@data.each {|a| yield a if a }
self
end
def to_a
@data.map(&:to_a)
end
alias to_ary to_a
def to_s
to_a.to_s
end
def inspect
to_a.inspect
end
def ==(other)
self.class == other.class && to_a == other.to_a
end
alias eql? ==
def <=>(other)
to_a <=> other.to_a if self.class == other.class
end
def size
count
end
def row(i)
@data ||= Array.dimension(@dimension - 1)
end
def first(n = nil)
n ? n.times.map {|i| row(i) } : row(0)
end
def clear
@data.clear
self
end
def map(&block)
return to_enum(__method__) unless block
Array::MultiDimensional.from_data @dimension,
@data.map {|a| a.map(&block) if a }
end
def map!(&block)
return to_enum(__method__) unless block
each_row {|a| a.map!(&block) }
self
end
alias collect map
alias collect! map!
def compact
Array::MultiDimensional.from_data @dimension,
@data.map {|a| a.compact if a }
end
def compact!
each_row.count {|a| a.compact! }.zero? ? nil : self
end
def flatten
each.to_a
end
def hash
@dimension.hash ^ to_a.hash
end
def find_index(*value)
return to_enum(__method__) if value.empty? && !block_given?
if block_given?
each_with_index {|e, *i| return i if yield e }
else
each_with_index {|e, *i| return i if e == value.first }
end
nil
end
alias index find_index
def empty?
count == 0
end
def delete(obj, &block)
each_row.map {|a| a.delete(obj, &block) }.find {|a| !a.nil? }
end
alias delete_at slice!
def delete_if(&block)
return to_enum(__method__) unless block_given?
each_row {|a| a.delete_if(&block) }
self
end
def sample(*args)
flatten.sample(*args)
end
end
[/pre]
测试代码:[pre lang="ruby" line="1"]arr = Array.dimension(3)
arr[0][0][0] = 0
arr[0, 1, 2] = 1
arr[2, 2, 2, 2] = [2, 2] # 前两个2为索引,第3个2为start,第4个2为length
arr[2, 3, 1..3] = *3..5
arr #=> [[[0], [nil, nil, 1]], [], [[], [], [nil, nil, 2, 2], [nil, 3, 4, 5]]]
arr.join #=> "0122345"
arr.compact.map {|n| n + 1 } #=> [[[1], [2]], [], [[], [], [3, 3], [4, 5, 6]]]
arr.each_index.to_a #=> [[0, 0, 0], [0, 1, 0], [0, 1, 1], [0, 1, 2], [2, 2, 0], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 3, 0], [2, 3, 1], [2, 3, 2], [2, 3, 3]][/pre] |
|