Ruby:创建数组项";“随需应变”;
在Ruby with Hash中,我可以做到:Ruby:创建数组项";“随需应变”;,ruby,arrays,Ruby,Arrays,在Ruby with Hash中,我可以做到: h = Hash.new { |h,k| h[k] = "created #{k}" } 因此,每当我尝试使用散列中不存在的密钥访问一个项时,它都会调用该块并创建这个新项并使用该密钥存储 是否有类似的方法来处理阵列?默认情况下,不,我认为这是不可能的。如果你愿意做一些猴子补丁,你可以自己添加一个类似的方法。例如,通过使用接受块的get方法扩展Array,可以模拟所需的内容 当没有给出任何块时,get方法将像常规的[]一样工作。当您传递一个块且值为
h = Hash.new { |h,k| h[k] = "created #{k}" }
因此,每当我尝试使用散列中不存在的密钥访问一个项时,它都会调用该块并创建这个新项并使用该密钥存储
是否有类似的方法来处理阵列?默认情况下,不,我认为这是不可能的。如果你愿意做一些猴子补丁,你可以自己添加一个类似的方法。例如,通过使用接受块的
get
方法扩展Array
,可以模拟所需的内容
当没有给出任何块时,get
方法将像常规的[]
一样工作。当您传递一个块且值为nil
时,它将在索引i
处存储来自该块的任何结果
class Array
def get(i, &block)
return self[i] if !block || !self[i].nil?
self[i] = block.call(i)
end
end
array = [1, 2]
array.get(0) # => 1
array.get(5) # => nil
array.get(5) { |i| "Created index #{i}" } # => "Created index 5"
p array # => [1, 2, nil, nil, nil, "Created index 5"]
数组。新的
方法可以接收块。它传递元素的索引,块的结果存储在数组中
Array.new(3) { |index| index ** 2 }
# => [0, 1, 4]
但是,所有元素都将在调用该方法时创建。它们也将被存储在块中,没有办法阻止
我们可以将数组
子类化,并实现所需的散列
类行为
class CustomArray < Array
def [](index)
if super.nil? then @default_proc.call self, index end
super
end
end
class << CustomArray
def new(*arguments, **keyword_arguments, &block)
if arguments.empty? and block
super().tap do |array|
array.instance_variable_set :@default_proc, block
end
else super end
end
end
看着它跑
请注意,由于nil
的含义,此实现存在问题。在这种情况下,由于数组的工作方式,它被定义为空值,这在连续内存的上下文中是合理的。如果您将一个元素存储在大于数组大小的索引处,它将用nil
填充空格,以指示最后一个元素和刚刚插入的元素之间的空白
如果<代码> nIL/COD>是一个有意义的值,考虑使用<代码> hash 使用整数键,而不是<代码>数组 .< /P>可能的马克斯的副本,这不是同一个问题,尽管它有很多共同之处,但那里的答案不能为我的问题提供解决方案。(大小){|索引|块}将创建一个大小为
size
的数组,当我尝试访问以前不存在的密钥时,它将不会再次调用该块。我建议将该方法命名为fetch
。这将使其与哈希
API一致。此外,我认为读卡器方法不应隐式修改该数组。@MatheusMoreirafetch
已存在于数组中,它类似于[]
,但在索引超出范围时引发异常。我不想更改现有方法的语义。我只是向您展示可以添加替代方法。
array = CustomArray.new { |array, index| array[index] = index + 2 }
p array[10]
# => 12
p array
# => [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 12]