查看: 2377|回复: 7

[胡扯] 刚刚写了个小脚本,这里测试一下

[复制链接]

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2014-8-15 09:01:00 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 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]

点评

=_=干脆拿VC弄个多维数组的dll好了(大雾)  发表于 2014-8-15 09:13
在数组大小不固定的时候这货可能大概还有那么一点点用处……  发表于 2014-8-15 09:12
上面的代码主要就是两件事:一个是防止数组越界导致对nil调用[]方法,还有就是各种迭代器的处理  发表于 2014-8-15 09:09
我自己都把“相当没用”这东西加红字了……要说用处的话,就是一些迭代器的处理吧  发表于 2014-8-15 09:07
a=Array.new(n){Array.new(n)}这样就好了吧  发表于 2014-8-15 09:05
梦石
0
星屑
49
在线时间
376 小时
注册时间
2013-2-14
回帖
195
发表于 2014-8-15 09:09:26 | 显示全部楼层
交出触手我们还是好朋友_(:з」∠)_
回复

使用道具 举报

百合控

梦石
0
星屑
6548
在线时间
1275 小时
注册时间
2013-8-21
回帖
3522

开拓者

发表于 2014-8-15 11:08:02 | 显示全部楼层
一个小布丁
  1. class Array::MultiDimensional
  2.   def first(c = 1)
  3.     c.times.map{|i| row(i)}
  4.   end
  5. end
复制代码

点评

等我试一下不过确实没什么用  发表于 2014-8-15 11:35
不是一吗?我记得1.times{|i| p i} #=> 0的  发表于 2014-8-15 11:35
accepted. 不过你的也有问题,n默认值不应该是1(我也偷懒了,其实这里应该用可变参数)。反正这玩意儿没啥用删了得了  发表于 2014-8-15 11:27
萌新瑟瑟发抖
看到我请叫我去干活
回复

使用道具 举报

百合控

梦石
0
星屑
6548
在线时间
1275 小时
注册时间
2013-8-21
回帖
3522

开拓者

发表于 2014-8-15 11:41:23 | 显示全部楼层
本帖最后由 余烬之中 于 2014-8-15 11:55 编辑
余烬之中 发表于 2014-8-15 11:08
一个小布丁


1的结果应该是没有问题的 但是应该拆一层

用一维数组打比方

[0,1,2,3,4].first #=> 0 元素
[0,1,2,3,4].first(2) #=> [0, 1] 数组

另外

[0,1,2,3,4].first(1) #=> [0] 数组
[0,1,2,3,4].first(0) #=> [] 数组

所以改成这样
  1. class Array::MultiDimensional
  2.   def first(c = nil)
  3.     c.nil? ? row(0) : c.times.map{|i| row(i)}
  4.   end
  5. end
复制代码
===================

没 我就在这里编辑的 没有看到你编辑了……

点评

其实我就是这么做的你没有发现吗233  发表于 2014-8-15 11:52
萌新瑟瑟发抖
看到我请叫我去干活
回复

使用道具 举报

梦石
0
星屑
122
在线时间
552 小时
注册时间
2012-8-18
回帖
1392
发表于 2014-8-15 11:50:38 | 显示全部楼层
= =|||
我还是啥也不说好了
我要填坑!我要背单词!我要学日语!我要每天锻炼!
好吧呵呵= =
回复

使用道具 举报

聪仔

梦石
0
星屑
6187
在线时间
3077 小时
注册时间
2013-12-26
回帖
3076
发表于 2014-8-15 12:02:50 | 显示全部楼层
脚本触们的疯狂自拍,我还是走远一点的好...

点评

聪仔怎么可以走开呢?应该和他们共同探讨!  发表于 2014-8-15 15:09
聪聪全国第三帅...
他们都叫我【人赢聪】
我的RM能力雷达图:

回复

使用道具 举报

菜鸟飞呀飞 该用户已被删除
发表于 2014-8-15 16:02:55 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

 楼主| 发表于 2014-8-15 16:26:05 | 显示全部楼层
本帖最后由 taroxd 于 2014-8-15 16:31 编辑
菜鸟飞呀飞 发表于 2014-8-15 16:02
无责简单弄了个,还是用Table是最好的,虽然有很多限制,用它当index也是可行的


感谢指导!简直就是一个Hash呢。

不过按我的想法,要“按顺序遍历”这个“多维数组”是不是有点麻烦呢?如果预先不知道这个“多维数组”的 xsize,ysize,zsize 的话。
毕竟如果不需要“按顺序遍历”的功能,直接用 Hash 就好了啦。比如独立开关那样的

话说,写了这玩意儿我自己都不会使用的。肯定是 Array.new(n) { Array.new(n) { Array.new } } } 了
上面那一大串破玩意儿,除了 [](*) 方法真的是没啥用。
我自己也不知道写这些东西是要做什么。

说到Hash我又想到了Set库,还有兰触给我做的题来着……感觉Hash真是各种好用。

点评

写着玩无压力无责任ohyeah~  发表于 2014-8-15 16:42
嗯 一般用Table就足够.....  发表于 2014-8-15 16:39
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部