在 Ruby 中,使用 1D Array,我可以通過Integer在括號中傳遞鍵來動態選擇元素,如下所示:
example = [0,1,2,[3,4]]
i = 2
example[i]
==> 2
我想要實作的是Array通過傳遞一個Arrayof來動態更新多維中的元素Integers,每個元素代表要在每個陣列中選擇的索引。我想要實作的示例:
example = [0,1,2,[3,4]]
path = [3, 1] (corresponds to the 4)
example[*path or some other syntax] = 9
example
==> [0,1,2,[3,9]]
我試過的是存盤每個路徑迭代的結果:
temp = example
path.each {|index|
temp = temp[index]
}
temp
==> 4
這成功地識別了我想要更新的元素。但是,它似乎存盤了一個副本,而不是參考原始位置,如下所示:
temp = 9
example
==> [0,1,2,[3,4]]
如何在example沒有path單獨括號中硬編碼的情況下更新基本陣列?
評論后澄清:我path事先不知道長度,這就是硬編碼不可行的原因。
uj5u.com熱心網友回復:
你的迭代就快到了,你只需要在運行之前停止一個步驟,path這樣你就可以擁有需要修改的陣列而不是元素。
所以把它path分成你想要的部分:
*p, target = path
# [3], 1
然后使用#inject查找陣列:
ary = p.inject(example) { |i, a| a[i] }
# [3, 4]
然后做你的任務:
ary[target] = 9
當然,您需要添加一些邏輯來處理意外情況,例如將path您引向非陣列元素或path不匹配的結構example(path = [11, 6, 23]在您的示例中考慮)。
您也可以使用#dig代替#inject:
ary = example.dig(*p)
ary[target] = 9
# or
example.dig(*p)[target] = 9
這將解決一些有問題的paths 并且您將決定如果ary.nil?.
uj5u.com熱心網友回復:
定義一個函式,類似于:
def deep_set! val, arr, *path
path[0...-1].each {|i| arr = arr[i]}
arr[path[-1]] = val
end
arr = [0,1,2,[3,4]]
deep_set! 9, arr, 3 ,1
arr #=> [0, 1, 2, [3, 9]]
uj5u.com熱心網友回復:
我假設path至少包含一個元素。
你可以使用Array#dig。
def dig_and_replace(arr, path, replacement)
*first, last = path
if first.empty?
arr[last] = replacement
else
arr.dig(*first)[last] = replacement
end
arr
end
arr = [0,1,2,[3,4]]
dig_and_replace(arr,[3,1],99)
#=> [0,1,2,[3,99]]
arr
#=> [0,1,2,[3,99]]
dig_and_replace([0,1,2,[3, 4 ]],[3,1],
{cat:'meow', dog:'woof'})
#=> [0,1,2,[3,{:cat=>"meow", :dog=>"woof"}]]
dig_and_replace([0,[1,[2,3,[4,5,[6, 7],8],9],10,11]],[1,1,2,2,1],99)
#=> [0,[1,[2,3,[4,5,[6,99],8],9],10,11]]
dig_and_replace([0,[1,[2,3,[4,5,[6,7],8],9],10,11]],[1,1,2],99)
#=> [0,[1,[2,3, 99, 9],10,11]]
請注意,如果
path = [1,2,3,4]
*first, last = path
然后
first #=> [1,2,3]
last #=> 4
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/389766.html
