我正在修補Array類以添加一個Array#sample!方法:
Array#sample!應該是Array#sample從陣列中洗掉回傳元素的破壞性版本 。Array#sample!應該采用與Array#sample.
但是,我無法正確傳遞引數。這是我正在嘗試的:
class Array
def sample!(n = nil, **args)
if n
self.sample(n, args).map { |e| self.delete(e) }
else
self.delete(self.sample(args))
end
end
end
a = (1..10).to_a
p a.sample
p a.sample(4)
p a.sample(random: Random.new(1))
p a.sample(4, random: Random.new(1))
p a.sample!
p a.sample!(4)
p a.sample!(random: Random.new(1))
p a.sample!(4, random: Random.new(1))
它失敗并顯示一條no implicit conversion of Hash into Integer訊息:o(
uj5u.com熱心網友回復:
讓我們從傳遞引數開始。您可以這樣做:(*如果n是,則 splat ( ) 有效地省略了位置引數nil)
class Array
def my_sample(n = nil, **kwargs)
sample(*n, **kwargs)
end
end
[1, 2, 3].my_sample #=> 3
[1, 2, 3].my_sample(2) #=> [1, 3]
[1, 2, 3].my_sample(random: Random.new(1)) #=> 2
[1, 2, 3].my_sample(2, random: Random.new(1)) #=> [2, 3]
或者你可以使用條件:
class Array
def my_sample(n = nil, **kwargs)
if n
sample(n, **kwargs)
else
sample(**kwargs)
end
end
end
實作一種sample!作業方式類似sample但同時洗掉這些元素的方法可能比您的方法復雜一些。
由于陣列可以多次包含相同的元素,因此您必須特別注意洗掉正確的元素。(您不能只洗掉所有重復項,也不能是任意的)
像這樣的事情可能會奏效:
class Array
def sample!(n = nil, **kwargs)
indices = (0...size).to_a
if n
samples = indices.sample(n, **kwargs)
remaining = indices - samples
return_value = values_at(*samples)
else
sample = indices.sample(**kwargs)
remaining = indices - [sample]
return_value = at(sample)
end
replace(values_at(*remaining))
return_value
end
end
在這里,我正在創建一個索引陣列(保證是唯一的)并從該陣列中取樣。然后我確定剩余的索引(這只是差異),設定回傳值并調整陣列內容。
您可以統一兩個代碼路徑,但這會使代碼更難閱讀。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/380714.html
標籤:红宝石
