gpt4 book ai didi

ruby - 我可以使用默认值在 Ruby 中创建数组吗?

转载 作者:数据小太阳 更新时间:2023-10-29 06:24:39 27 4
gpt4 key购买 nike

Perl 对默认值非常友好:

: jmglov@laurana; perl -e '@foo; printf "%d\n", $foo[123]'
0
: jmglov@laurana; perl -e '%foo; printf "%d\n", $foo{bar}'
0

Ruby 可以做同样的事情,至少对于哈希:

>> foo = Hash.new(0)
=> {}
>> foo[:bar]
=> 0

但同样的方法似乎不适用于数组:

>> foo = Array.new(0)
=> []
>> foo[123]
=> nil
>> foo[124] = 0
=> 0
>> foo[456] = 0
=> 0
>> foo[455,456]
=> [nil, 0]

是否可以为数组提供一个默认值,这样当它们被自动扩展时,它们被填充为 0 而不是 nil?

当然我可以解决这个问题,但要以表现力为代价:

>> foo[457,458] = 890, 321
=> [890, 321]
>> foo[456] += 789
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+
>> foo.inject(0) {|sum, i| sum += (i || 0) }
=> 1211
>> foo.inject(:+)
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+

更新 1: 我的一位同事指出我可以使用 #compact 来解决 #inject 问题,并且 #to_i 解决标准元素索引问题:

>> foo.include? nil
=> true
>> foo.compact.inject(:+)
=> 1211
>> foo[456,457]
=> [0, 890, 321]
>> foo[455..457]
=> [nil, 0, 890]
>> foo[455..457].map(&:to_i)
=> [0, 0, 890]

更新 2:感谢 Andrew Grimm+= 问题的解决方案:

>> foo = []
=> []
>> def foo.[](i)
>> fetch(i) {0}
>> end
=> nil
>> foo[4]
=> 0
>> foo
=> []
>> foo[4] += 123
=> 123
>> foo
=> [nil, nil, nil, nil, 123]

更新 3:这看起来像打地鼠!

>> foo
=> [nil, nil, nil, nil, 123]
>> foo[-2..-1]
TypeError: can't convert Range into Integer

但我们可以处理:

>> def foo.[](index)
>> if index.is_a? Range
>> index.map {|i| self[i] }
>> else
?> fetch(index) { 0 } # default to 0 if no element at index; will not cause auto-extension of array
>> end
>> end
=> nil
>> foo
=> [nil, nil, nil, nil, 123]
>> foo[-2..-1]
=> [nil, 123]

我现在不得不(不好意思地)承认我将子类化 Array 以避免使我的代码困惑:

class MyClass
class ArrayWithDefault < Array
def [](index)
if index.is_a? Range
index.map {|i| self[i] }
else
fetch(index) { 0 } # default to 0 if no element at index; will not cause auto-extension of array
end
end
end
end

感谢所有创造性的解决方案。确实是 TIMTOWTDI!

最佳答案

不是自动扩展,而是用默认值初始化为指定长度:

>> Array.new(123, 0)  
=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

关于ruby - 我可以使用默认值在 Ruby 中创建数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5324654/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com