2011-07-03 102 views
2

我有一個名爲user的對象。我可以通過user.name得到它的名字,它的名字和姓氏都有,例如Jon Doe。抓住第一個字符到空格字符的最有效和最優雅的方式是什麼,以便我得到Jon從索引0提取子字符串直至搜索字符

+5

對於破解這將工作(順便說一句它屬於中'User'類,以便你說'user.first_name','不是user.name.split.first'),但我認爲你應該考慮在'User'類中構建'first_name'和'last_name'的功能,而不是依賴於未指定的格式,這可能會導致呃RORS。即(你應該保留它們作爲單獨的屬性,然後將它們合併爲名稱:'class User; def name;「#{first_name}#{last_name}」end end') –

回答

3

下面將拆分空格上的字符串,並將輸出第一個元素(在你的情況下,這將是第一個名稱)。

user.name.split[0] 
5

我會說:

s.split[0] # s = user.name 

s.split.first 

這些都分裂上的空白串入一個字符串數組,並返回第一個元素。即使只給出一個名字而不是第一個和最後一個,它仍然可以工作。

1

我很好奇,什麼是最快的解決方案。我的結果是the regex of Wayne

關於分割的一句話:如果你的名字有更多的部分,你可能會在第一次分割後停下來。您可以與

String#split(/\s/, 2) 

我的基準做到這一點:

require 'benchmark' 

TEST_LOOPS = 10_000_000 
NAME = 'Jon Doe the third' 

#~ p NAME.split[0] 
#~ p NAME.split.first 
#~ p NAME[/^\S*/] 
#~ p NAME.split(/\s/, 2).first 
#~ p NAME.split(/\s/, 2)[0] 
#~ p NAME.split(' ', 2)[0] 
#~ exit 

Benchmark.bmbm(10) {|b| 

    b.report('[0]') { 
    TEST_LOOPS.times { 
     NAME.split[0] 
    }   #Testloops 
    }    #b.report 

    b.report('[0]2regex') { 
    TEST_LOOPS.times { 
     NAME.split(/\s/, 2)[0] 
    }   #Testloops 
    }    #b.report 
    b.report('[0]2string') { 
    TEST_LOOPS.times { 
     NAME.split(' ', 2)[0] 
    }   #Testloops 
    }    #b.report 

b.report('first') { 
    TEST_LOOPS.times { 
     NAME.split.first 
    }   #Testloops 
    }    #b.report 
    b.report('first2regex') { 
    TEST_LOOPS.times { 
     NAME.split(/\s/, 2).first 
    }   #Testloops 
    }    #b.report 
    b.report('first2string') { 
    TEST_LOOPS.times { 
     NAME.split(' ', 2).first 
    }   #Testloops 
    }    #b.report 
    b.report('regex') { 
    TEST_LOOPS.times { 
     NAME[/^\S*/] 
    }   #Testloops 
    }    #b.report 

    b.report('dollar backtick') { 
    TEST_LOOPS.times { 
     NAME =~// 
     $` 
    }   #Testloops 
    }    #b.report 

} #Benchmark 

結果:

Rehearsal --------------------------------------------------- 
[0]    30.453000 0.797000 31.250000 (31.311608) 
[0]2regex  21.094000 0.000000 21.094000 (23.651419) 
[0]2string  19.188000 0.000000 19.188000 (20.999215) 
first   34.187000 0.782000 34.969000 (39.935742) 
first2regex  24.078000 0.000000 24.078000 (26.813530) 
first2string  19.125000 0.000000 19.125000 (19.411310) 
regex   13.094000 0.000000 13.094000 (13.242792) 
dollar backtick 12.219000 0.000000 12.219000 (12.227719) 
---------------------------------------- total: 175.017000sec 

         user  system  total  real 
[0]    30.859000 0.734000 31.593000 (33.809723) 
[0]2regex  20.891000 0.000000 20.891000 (21.156553) 
[0]2string  18.890000 0.000000 18.890000 (19.997051) 
first   32.516000 0.812000 33.328000 (36.216360) 
first2regex  22.000000 0.000000 22.000000 (22.853772) 
first2string  19.781000 0.000000 19.781000 (22.010805) 
regex   13.359000 0.000000 13.359000 (14.892417) 
dollar backtick 12.328000 0.000000 12.328000 (13.253315) 
+0

如果我將結果合併到答案中? –

+0

沒關係,就這樣做。 – knut

3
$` 

就是你要找正是爲。

"John Doe" =~// 
$` # => "John" 

它也比在克努特的回答中列出的其它快:

require 'benchmark' 

TEST_LOOPS = 10_000_000 
NAME = 'Jon Doe the third' 

#~ p NAME.split[0] 
#~ p NAME.split.first 
#~ p NAME[/^\S*/] 
#~ p NAME.split(/\s/, 2).first 
#~ p NAME.split(/\s/, 2)[0] 
#~ p NAME.split(' ', 2)[0] 
#~ exit 

Benchmark.bmbm(10) {|b| 

    b.report('[0]') { 
    TEST_LOOPS.times { 
     NAME.split[0] 
    }   #Testloops 
    }    #b.report 

    b.report('[0]2regex') { 
    TEST_LOOPS.times { 
     NAME.split(/\s/, 2)[0] 
    }   #Testloops 
    }    #b.report 
    b.report('[0]2string') { 
    TEST_LOOPS.times { 
     NAME.split(' ', 2)[0] 
    }   #Testloops 
    }    #b.report 

b.report('first') { 
    TEST_LOOPS.times { 
     NAME.split.first 
    }   #Testloops 
    }    #b.report 
    b.report('first2regex') { 
    TEST_LOOPS.times { 
     NAME.split(/\s/, 2).first 
    }   #Testloops 
    }    #b.report 
    b.report('first2string') { 
    TEST_LOOPS.times { 
     NAME.split(' ', 2).first 
    }   #Testloops 
    }    #b.report 
    b.report('regex') { 
    TEST_LOOPS.times { 
     NAME[/^\S*/] 
    }   #Testloops 
    }    #b.report 

    b.report('dollar backtick') { 
    TEST_LOOPS.times { 
     NAME =~// 
     $` 
    }   #Testloops 
    }    #b.report 

} #Benchmark 

給人

Rehearsal --------------------------------------------------- 
[0]    30.453000 0.797000 31.250000 (31.311608) 
[0]2regex  21.094000 0.000000 21.094000 (23.651419) 
[0]2string  19.188000 0.000000 19.188000 (20.999215) 
first   34.187000 0.782000 34.969000 (39.935742) 
first2regex  24.078000 0.000000 24.078000 (26.813530) 
first2string  19.125000 0.000000 19.125000 (19.411310) 
regex   13.094000 0.000000 13.094000 (13.242792) 
dollar backtick 12.219000 0.000000 12.219000 (12.227719) 
---------------------------------------- total: 175.017000sec 

         user  system  total  real 
[0]    30.859000 0.734000 31.593000 (33.809723) 
[0]2regex  20.891000 0.000000 20.891000 (21.156553) 
[0]2string  18.890000 0.000000 18.890000 (19.997051) 
first   32.516000 0.812000 33.328000 (36.216360) 
first2regex  22.000000 0.000000 22.000000 (22.853772) 
first2string  19.781000 0.000000 19.781000 (22.010805) 
regex   13.359000 0.000000 13.359000 (14.892417) 
dollar backtick 12.328000 0.000000 12.328000 (13.253315)