这就是我现在拥有的东西,它有点工作:
def padding(a, b, c=nil)
until a[b-1]
a << c
end
end
这就是它的工作原理:
a=[1,2,3]
padding(a,10,"YES")
=>[1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
a[1,2,3]
padding(a,10,1)
=>[1, 2, 3, 1, 1, 1, 1, 1, 1, 1]
但是当我没有为&#34; c&#34;
输入值时它会崩溃a=[1,2,3]
padding(a,10)
Killed
我应该如何追加它以避免崩溃? 另外,您如何建议更改此方法以使用它:
[1,2,3].padding(10)
=>[1,2,3,nil,nil,nil,nil,nil,nil,nil]
[1,2,3].padding(10, "YES")
=>[1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
我在SO上看过其他填充方法,但它们似乎并没有像作者那样按预期工作。所以,我决定自己动手。
答案 0 :(得分:13)
您知道Array#fill
方法: -
确实如此,你究竟在寻找什么。如果它存在,为什么你想要自己的。
arup@linux-wzza:~> pry
[1] pry(main)> a=[1,2,3]
=> [1, 2, 3]
[2] pry(main)> a.fill('YES', 3...10)
=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
[3] pry(main)>
您可以填写您的数组,无论您想要什么。这是一个很酷的实现。试一试。
在你的控制台中阅读:
arup@linux-wzza:~> ri Array#fill
= Array#fill
(from ruby site)
------------------------------------------------------------------------------
ary.fill(obj) -> ary
ary.fill(obj, start [, length]) -> ary
ary.fill(obj, range ) -> ary
ary.fill { |index| block } -> ary
ary.fill(start [, length] ) { |index| block } -> ary
ary.fill(range) { |index| block } -> ary
------------------------------------------------------------------------------
The first three forms set the selected elements of self (which may be the
entire array) to obj.
A start of nil is equivalent to zero.
A length of nil is equivalent to the length of the array.
The last three forms fill the array with the value of the given block, which
is passed the absolute index of each element to be filled.
Negative values of start count from the end of the array, where -1 is the last
element.
a = [ "a", "b", "c", "d" ]
a.fill("x") #=> ["x", "x", "x", "x"]
a.fill("z", 2, 2) #=> ["x", "x", "z", "z"]
a.fill("y", 0..1) #=> ["y", "y", "z", "z"]
a.fill { |i| i*i } #=> [0, 1, 4, 9]
a.fill(-2) { |i| i*i*i } #=> [0, 1, 8, 27]
答案 1 :(得分:5)
它被杀死了,因为你正在进入无限循环。 until a[b-1]
将无法完成,因为当您向数组添加nils时,您将获得:
a == [1, 2, 3, nil, nil, nil, nil, nil, nil, nil]
经过几次迭代后,[b-1]将为nil
,这是假的。直到永远不会停止。
关于第二个问题,扩展现有的Array类很容易:
class Array
def padding(i, value=nil)
(i - length).times { self << value }
self
end
end
按预期结果:
[1,2,3].padding(10)
#=> [1, 2, 3, nil, nil, nil, nil, nil, nil, nil]
[1,2,3].padding(10, "YES")
#=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
请注意关于修改现有数组的方法(因为Ruby约定应该被称为padding!
):
a = [1,2,3]
#=> [1, 2, 3]
a.padding(10, "YES")
#=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
a
#=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
但是当然你可以轻松创建不修改的方法版本。我假设您要修改数组,因为您的原始方法是这样做的。
答案 2 :(得分:3)
Arup已经钉了它,但这是另一种方式:
def padding(a,b,c)
[*a, *[c]*b]
end
a=[1,2,3]
padding(a,5,"YES")
#=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES"]
答案 3 :(得分:2)
问题是nil被评估为false,所以当[b-1]包含nil时,until a[b-1]
永远不会为真...所以你永远循环直到你的内存不足。
最好做...
def padding(a, b, c=nil)
until a.size >= b
a << c
end
end
EDIT (是的,Arup的答案非常简洁)
你可以做一个单行,这个更紧凑......
def padding(a, b, c=nil)
a << c until a.size >= b
end
答案 4 :(得分:0)
在Array上专门实现padding
方法:
module Padding
refine Array do
def padding(new_length, element=nil)
if self.size < new_length
self.concat(Array.new(new_length - self.size, element))
end
end
end
end
using Padding
puts [1,2,3].padding(10).inspect
# => [1, 2, 3, nil, nil, nil, nil, nil, nil, nil]
puts [1,2,3].padding(10, "YES").inspect
# => [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
编辑:忘记了Array#fill
。 Arup的答案很酷(即使你需要说fill(3, 7)
而不是fill(-1, 10)
,因为后者给出了错误的结果)。最好使用它而不是concat(Array.new(...))
。嗯好吧。 :)