Извлечь подстроку из индекса 0 до искомого символа - PullRequest
2 голосов
/ 04 июля 2011

У меня есть объект с именем user.Я могу получить его имя по user.name, и его значение имеет как имя, так и фамилию, например Jon Doe.Какой самый эффективный и элегантный способ получить первый символ до пробела, чтобы я получил Jon?

Ответы [ 4 ]

5 голосов
/ 04 июля 2011

Я бы сказал:

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

или

s.split.first

Они оба разбивают строку на пустом месте на массив строк и возвращают первый элемент.Он все равно будет работать, даже если вместо первого и последнего указано только одно имя.

3 голосов
/ 04 июля 2011
$`

это именно то, что вы ищете.

"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)
3 голосов
/ 04 июля 2011

Следующее разделит строку на пробелы и выведет первый элемент (в вашем случае это будет первое имя).

user.name.split[0]
1 голос
/ 04 июля 2011

Мне было любопытно, какое самое быстрое решение. Мой результат был регулярное выражение Уэйна .

Одно слово о разделении: если ваше имя содержит больше частей, вы можете остановиться после первого разделения. Вы можете сделать это с

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...