2011-02-10 111 views
13

我正在通過Project Euler我的方式工作,並遇到了一個有點令人驚訝的遺漏:沒有String#shift,unshift,pushpop。我假定一個String被認爲是一個像Array這樣的「順序」對象,因爲它們共享索引和迭代的能力,並且這包括能夠輕鬆更改對象的開始和結束的能力。爲什麼沒有String#shift()?

我知道有辦法創造相同的效果,但有沒有一個特定的原因,字符串確實不是有這些方法?

+1

可能是因爲如果字符串有這些方法,人們會使用它們。這將是一件壞事。另見:「成功之坑」。你不希望最簡單的方法也是錯誤的方式。 – Jimmy 2011-02-10 23:31:48

+0

爲什麼它會是一件壞事? – Zabba 2011-02-10 23:32:26

+0

@Zabba:在很多語言中,字符串都是不可變的。這可以讓你擺脫像國際表這樣的詭計,但也意味着如果你堅持對字符串進行大量變異,這是非常低效的。最經典的例子就是.NET的「gotcha」面試問題「以下代碼出了什麼問題?」 (這就像`bar =「」; foreach(var foo in frob)bar + = foo;`) – Jimmy 2011-02-10 23:45:26

回答

11

字符串不充當1.9中的可枚舉對象,因爲它被認爲太混亂以至於無法確定它將成爲一個列表:

  • 字符/碼點列表?
  • 字節列表?
  • 行列表?
5

不是Ruby的貢獻者,我不能說他們的設計目標,但從經驗來說,我不認爲字符串被認爲是'順序'的對象;它們以可以提示順序行爲的方式變化,但大多數情況下它們都是以原子方式處理的。例子:在Ruby 1.9中,String不再混合Enumerable

5
>> mystring = "abcdefgh" 
=> "abcdefgh" 
>> myarray = mystring.split("") 
=> ["a", "b", "c", "d", "e", "f", "g", "h"] 
>> myarray.pop 
=> "h" 
>> mystring = myarray.join 
=> "abcdefg" 

這應該這樣做,你wouldhave將其轉換爲一個數組,然後回雖然

UPDATE:

使用String#chop!Stirng#<<

>> s = "abc" 
=> "abc" 
>> s.chop! 
=> "ab" 
>> s 
=> "ab" 
>> s<<"def" 
=> "abdef" 
>> s 
=> "abdef" 
>> 
2

至少在1.9.2中,你可以處理像數組這樣的字符串。

ruby-1.9.2-p290 :001 > "awesome"[3..-1] => "some" 

所以,如果你想要做一個排序字符左移,只是使用[1 ..- 1]

ruby-1.9.2-p290 :003 > "fooh!"[1..-1] => "ooh!"