2013-07-14 55 views
27
things = "one thing, two things, three things, four things" 

給出這個輸入,我該如何用逗號分割一個字符串,然後修剪它周圍的空白處?導致:Ruby:分割,然後刪除前導/尾隨空白?

things = ["one thing", "two things", "three things", "four things"] 

目前我有這樣的:

things = things.to_s.tr("\n\t", "").strip.split(/,/) 

這確實最什麼,我想要它做的,除了刪除前/後空格時,它分裂的逗號。達到此目的的最佳方式是什麼?我想把它作爲這個表達式的一部分,而不是將上面的結果分配給一個單獨的數組,並迭代它。

+0

字符串''一件事,兩件事,三件事,四件事''和'{:東西=>東西.to_s.tr(「\ n \ t「,」「).strip.split(/,/)}'?不要只是複製你擁有的任何東西。把它變成一個你能夠理解的問題。刪除不相關的東西。 – sawa

+0

好的,我已經完成了。 :-) – Ben

回答

63
s = "one thing, two things, three things, four things" 
s.split(",").map(&:strip) 
# => ["one thing", "two things", "three things", "four things"] 

在我的Ubuntu 13.04 OS,使用紅寶石2.0.0p0

require 'benchmark' 

s = "one thing, two things, three things, four things" 
result = "" 

Benchmark.bmbm do |b| 
    b.report("strip/split: ") { 1_000_000.times {result = s.split(",").map(&:strip)} } 
    b.report("regex: ") { 1_000_000.times {result = s.split(/\s*,\s*/)} } 
end 

Rehearsal ------------------------------------------------- 
strip/split: 6.260000 0.000000 6.260000 ( 6.276583) 
regex:   7.310000 0.000000 7.310000 ( 7.320001) 
--------------------------------------- total: 13.570000sec 

        user  system  total  real 
strip/split: 6.350000 0.000000 6.350000 ( 6.363127) 
regex:   7.290000 0.000000 7.290000 ( 7.302163) 
+2

完美。非常感謝! – Ben

+1

請注意,這個解決方案比我的基於正則表達式的解決方案慢大約2倍。 – Koraktor

+1

@Koraktor你有沒有實際計時?有時候Ruby會讓我感到驚訝。 – pjs

6

使用#split正則表達式:

"one thing, two things, three things, four things".split /\s*,\s*/ 
# => ["one thing", "two things", "three things", "four things"] 
2

這並不意味着作爲一個答案到原來的問題,但我想分享基準代碼,讓人們檢查兩個提出的解決方案本身:

require 'benchmark' 

s = "one thing, two things, three things, four things" 
result = "" 

Benchmark.bmbm do |b| 
    b.report("strip/split: ") { 1_000_000.times {result = s.split(",").map(&:strip)} } 
    b.report("regex: ") { 1_000_000.times {result = s.split(/\s*,\s*/)} } 
end 

在我的系統(紅寶石2.0.0p247在OS X 10.8),其產生以下輸出:

Rehearsal ------------------------------------------------- 
strip/split: 2.140000 0.000000 2.140000 ( 2.143905) 
regex:   3.570000 0.010000 3.580000 ( 3.572911) 
---------------------------------------- total: 5.720000sec 

        user  system  total  real 
strip/split: 2.150000 0.000000 2.150000 ( 2.146948) 
regex:   3.580000 0.010000 3.590000 ( 3.590646) 

這些結果可以,當然,可以預料到紅寶石版本之間變化,硬件和操作系統。

+0

* + 1 *用於顯示您的*基準*報告。 –

3

不是要打死一匹死馬,但是現在可以通過對我進行兩次變更來加速這一點。第一種是使用map!而不是map來避免創建拆分數組的副本,第二種是避免使用該符號來處理語法(例如,&:split,它增加了一個額外的操作,可以通過更詳細的語法來避免) 。

基準如下:

require 'benchmark' 

s = "one thing, two things, three things, four things" 
result = "" 

Benchmark.bmbm do |b| 
    b.report("strip/split (map/to_proc): ") { 1_000_000.times { result = s.split(",").map(&:strip) } } 
    b.report("strip/split (map): ") { 1_000_000.times { result = s.split(",").map { |e| e.strip } } } 
    b.report("strip/split (map!/to_proc): ") { 1_000_000.times { result = s.split(",").map!(&:strip) } } 
    b.report("strip/split (map!): ") { 1_000_000.times { result = s.split(",").map! { |e| e.strip } } } 
    b.report("regex: ") { 1_000_000.times { result = s.split(/\s*,\s*/) } } 
end 

結果:

        user  system  total  real 
strip/split (map/to_proc):  5.230000 0.010000 5.240000 ( 5.283079) 
strip/split (map):    4.660000 0.010000 4.670000 ( 4.716920) 
strip/split (map!/to_proc): 4.440000 0.020000 4.460000 ( 4.492943) 
strip/split (map!):   4.320000 0.010000 4.330000 ( 4.365386) 
regex:       7.190000 0.060000 7.250000 ( 7.322932) 

請務必閱讀彼此相對的數字,而不是相對於在其他的答案中提供的基準。

+0

感謝您的回答,有趣的是看到稍微更冗長的語法擊敗了一個更加細節的語法。 :-) – Ben

+0

@Ben我的榮幸。 Terser通常等同於更多的「魔法」,更多的魔法意味着更多的操作,更多的操作意味着更慢的性能:) – xentek

6

我喜歡測試......但是我們要面對它,除非您在代碼中執行百萬次循環內的這個操作,否則速度差異是沒有意義的。

因此,最好的解決方案可能是最清晰的解決方案。也許這一個由奧雅納Rakshit:

s = "one thing, two things, three things, four things" 
s.split(",").map!(&:strip) 
+2

您的解決方案與我的完全相同.. * dup *需要什麼? –

+0

我猜你沒看過我寫的東西。 「 」...最好的解決方案可能是最清晰的解決方案...「 我的評論不是關於*你的*解決方案(或*任何*特定的解決方案),而是關於衡量速度vs清晰/簡單。換句話說,誰在乎它是否更快 - 除非您的實際情況要求優化代碼。爲了自身利益而進行的早期優化通常是增加技術債務的祕訣。 –

+0

我把*基準*也存在..所以很明顯,從基準報告哪一個更快。 :-) –

1

如果我沒有記錯

things.split(", ") 

將是最簡單的解決方案。但是,它只適用於只有一個空格字符的情況。 (注意逗號後的空格)

相關問題