2017-09-03 137 views
2

我不知道這是如何變量稱爲origString在我的循環變量改變值,紅寶石

def scramble_string(string, positions) 
    i = 0 
    origString = string 
    puts origString 
    newString = string 
    while i < string.length 
    newString[i] = origString[positions[i]] 
    i = i + 1 
    end 
    puts origString 
    return newString 
end 

變更值,例如,如果我運行scramble_string(「ABCD」,[3,1,2,... 0] ) origString從第一個「puts」中的「abcd」更改爲第二個中的「dbcd」。 如果我只聲明一次,我如何更改origString的值?

+1

Ruby強烈建議使用像'orig_string'這樣的名稱,不要使用大寫字母,因爲大小寫在Ruby中具有重要意義。 – tadman

+0

該變量不會更改其值。價值正在改變其內容,因爲你告訴它在第7行。 –

+0

@JörgWMittag你可以詳細說明嗎?它的工作原理「價值在改變其內容」。 – Aparichith

回答

4

當您在Ruby中說x = y時,它會創建一個引用了完全相同對象的變量。到x任何修改都將應用到y,反之亦然:

y = "test" 
x = y 

x[0] = "b" 

x 
# => "best" 
y 
# => "best" 

你可以因爲這樣告訴:

x.object_id == y.object_id 
# => true 

他們是相同的對象。你想要的是做一個備份:

x = y.dup 
x[0] = "b" 
x 
# => "best" 
y 
# => "test" 

這將導致兩個獨立的對象:

x.object_id == y.object_id 
# => false 

所以你的情況,你需要的是改變它喜歡:

orig_string = string.dup 

現在有人說,通常在Ruby中處理事情的最佳方式是使用返回副本的函數,而不是操縱適當的東西。更好的解決方案是這樣的:

def scramble_string(string, positions) 
    (0...string.length).map do |p| 
    string[positions[p]] 
    end.join 
end 

scramble_string("abcd", [3, 1, 2, 0]) 
"dbca" 

請注意,這比字符串操作版本更簡潔。

+0

或'string.chars.values_at(* positions).join' – Stefan

+0

@tadman需要對您的陳述進行一些解釋。當我們說'x = y'時,兩個object_id是相同的,但是x [0]和y [0]的object_id是不同的。如果我們改變'x ='pest''的整個值,object_id將完全改變。但改變'x'中的單個值反映了原始字符串'y',如何? 需要更多地瞭解這一點。 – Aparichith

+0

'x [0]'返回一個單字符的子字符串。由於每個子字符串操作都可以生成*新的唯一字符串*,所以即使是'x [0] .object_id == x [0] .object_id'通常也是不正確的。只有一些object_id等同於設計:符號,零,真,假和*一些*數字。 – tadman