2011-07-03 12 views
2

私はuserというオブジェクトを持っています。私はuser.nameによってその名前を得ることができ、その値はJon Doeのような名と姓の両方を持っています。空白文字までの最初のキャラクターをつかむ最も効率的でエレガントな方法は、Jonになるのですか?インデックス0から検索文字までの部分文字列を抽出します

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

または

s.split.first 

これらの両方が文字列の配列に空白の文字列を分割し、最初の要素を返す:

+5

を与えます(ところで、それはそのように 'User'クラスに属し、 'user.name.split.first'ではなく' user.first_name'と言っていますが)、私は 'first_name'と' last_name'機能を 'User'クラスにビルドすることを検討すべきだと思います。これはerにつながる可能性が高いrors。 #{first_name}#{last_name} "end end') –

答えて

3

以下は、文字列をスペースで分割し、最初の要素を出力します(この場合、これが最初の名前になります)。

user.name.split[0] 
5

私は言うでしょう。それは最初と最後の両方の代わりに単一の名前だけが与えられても、やはり動作します。

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) 
関連する問題