2011-07-03 101 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)