Я отредактировал свой ответ, так что может быть возможно изменить выбранный ответ. Посмотрите, сможете ли вы присуждать его ответу Джейсона Стирка, поскольку он самый быстрый и хорошо читаемый.
Жестянщик
3
Используйте str [1 ..- 1], это быстрее всего согласно ответам ниже.
Ачют Растоги
1
Начиная с Ruby 2.5 вы можете использовать delete_prefixи delete_prefix!- подробнее ниже . У меня не было времени на тесты, но скоро сделаю!
SRack
Обновление: я протестировал новые методы ( delete_prefix\ delete_prefix!), и они довольно быстрые. Не совсем удачные предыдущие фавориты по скорости, но читабельность означает, что у них есть отличные новые возможности!
1.9.3
user system total real[0]0.8400000.0000000.840000(0.847496)
sub 1.9600000.0100001.970000(1.962767)
gsub 4.3500000.0200004.370000(4.372801)[1..-1]0.7100000.0000000.710000(0.713366)
slice 1.0200000.0000001.020000(1.020336)
length 1.1600000.0000001.160000(1.157882)
Обновление, чтобы включить еще один предложенный ответ:
2.1.2
user system total real[0]0.3000000.0000000.300000(0.295054)
sub 0.6300000.0000000.630000(0.631870)
gsub 2.0900000.0000002.090000(2.094368)[1..-1]0.2300000.0100000.240000(0.232846)
slice 0.3200000.0000000.320000(0.320714)
length 0.3400000.0000000.340000(0.341918)
eat!0.4600000.0000000.460000(0.452724)
reverse 0.4000000.0000000.400000(0.399465)
И еще одно использование, /^./чтобы найти первого персонажа:
Вот еще одно обновление более быстрого оборудования и более новой версии Ruby:
2.3.1
user system total real[0]0.2000000.0000000.200000(0.204307)[/^./]0.3900000.0000000.390000(0.387527)[/^\[/]0.3600000.0000000.360000(0.360400)
sub+0.4900000.0000000.490000(0.492083)
sub 0.4800000.0000000.480000(0.487862)
gsub 1.9900000.0000001.990000(1.988716)[1..-1]0.1800000.0000000.180000(0.181673)
slice 0.2600000.0000000.260000(0.266371)
length 0.2700000.0000000.270000(0.267651)
eat!0.4000000.0100000.410000(0.398093)
reverse 0.3400000.0000000.340000(0.344077)
Почему gsub такой медленный?
После выполнения поиска / замены gsubнеобходимо проверить наличие возможных дополнительных совпадений, прежде чем он сможет определить, завершено ли оно. subтолько делает один и заканчивает. Считайте, gsubчто это как минимум два subзвонка.
Кроме того, важно помнить об этом gsub, а subтакже может быть затруднен плохо написанным регулярным выражением, которое сопоставляется гораздо медленнее, чем поиск по подстроке. Если возможно, закрепите регулярное выражение, чтобы получить от него максимальную скорость. Здесь есть ответы на Stack Overflow, демонстрирующие это, поэтому ищите, если вам нужно больше информации.
+1 Посмотрите на результаты тестов, которые я добавил к своему ответу. У вас самое быстрое время выполнения, плюс я думаю, что это очень чисто.
Жестянщик
Как насчет производительности по str[1,]сравнению с вышеупомянутым?
Бор
1
@ Бор: str[1,]вернуть вам 2-й символ, поскольку диапазон 1:nil. Вам нужно будет str[1,999999]указать фактическую вычисленную длину или что-то, что гарантированно будет больше длины, например, (используйте, конечно, int_max), чтобы получить весь хвост. [1..-1]это чище и, вероятно, быстрее, так как вам не нужно работать с длиной вручную (см. [1..length] в тесте производительности)
quetzalcoatl
4
Очень хорошее решение. Кстати, если кто-то хочет удалить первый и последний символы:str[1..-2]
pisaruk
50
Мы можем использовать ломтик, чтобы сделать это:
val ="abc"=>"abc"
val.slice!(0)=>"a"
val=>"bc"
Используя slice!мы можем удалить любой символ, указав его индекс.
Этот элегантный slice!(0)ответ действительно должен быть выбран, так как использование asdf[0] = '' для удаления первого символа смешно (так же, как использование gsub с регулярным выражением и стрельба по мухе с помощью гаубицы).
f055
1
Хотя это может показаться на первый взгляд не интуитивным, []=но не требует столько базового кода C, где slice!требуется дополнительная работа. Это добавляет. Аргумент может быть «Что более читабельно?» Я нахожу использование []=читабельным, но я исхожу из фона C -> Perl, который, вероятно, окрашивает мое мышление. Разработчики Java, вероятно, подумают, что это менее читабельно. Любой из них является приемлемым способом решения этой задачи, если он прост в понимании и обслуживании и не требует чрезмерной загрузки ЦП.
Жестянщик
Хорошо. Знаете ли вы, как мы можем измерить, если функция принимает большую нагрузку на процессор в ROR? или мы должны использовать разницу во времени выполнения в миллисекундах или наносекундах?
balanv
18
Ruby 2.5+
Начиная с Ruby 2.5 вы можете использовать delete_prefixили delete_prefix!для достижения этого в удобочитаемой форме.
Используя настройку Tin Man, он тоже выглядит довольно быстро (под двумя последними записями delete_pи delete_p!). Не совсем уместен предыдущий фаворит для скорости, хотя очень читабелен.
2.5.0
user system total real
[0]0.1747660.0004890.175255(0.180207)[/^./]0.3180380.0005100.318548(0.323679)[/^\[/]0.3726450.0011340.373779(0.379029)
sub+0.4602950.0015100.461805(0.467279)
sub 0.4983510.0015340.499885(0.505729)
gsub 1.6698370.0051411.674978(1.682853)[1..-1]0.1998400.0009760.200816(0.205889)
slice 0.2796610.0008590.280520(0.285661)
length 0.2683620.0003100.268672(0.273829)
eat!0.3417150.0005240.342239(0.347097)
reverse 0.3353010.0005880.335889(0.340965)
delete_p 0.2222970.0008320.223129(0.228455)
delete_p!0.2257980.0007470.226545(0.231745)
Я бы использовал "[12,23,987,43".sub(/^\[+/, "")вместо gsub(/^\[/, ""). Первый позволяет механизму регулярных выражений находить все совпадения, затем они заменяются одним действием и приводят к увеличению скорости примерно в 2 раза с Ruby 1.9.3.
Жестянщик
1
Так как мы имеем дело со строками, это должно быть gsub(/\A\[/, "") ?
1.9.2-p290 > a ="One Two Three"=>"One Two Three"1.9.2-p290 > a = a[1..-1]=>"ne Two Three"1.9.2-p290 > a = a[1..-1]=>"e Two Three"1.9.2-p290 > a = a[1..-1]=>" Two Three"1.9.2-p290 > a = a[1..-1]=>"Two Three"1.9.2-p290 > a = a[1..-1]=>"wo Three"
Таким образом, вы можете удалить один за другим первый символ строки.
Если вы хотите сохранить семантику «рубить», вы можете просто"[12,23,987,43".reverse.chop.reverse
Крис Хилд
это довольно большие потери производительности, чтобы убрать один символ
Пабло Фернандес
7
почему бы не использовать [1 ..- 1] вместо [1..self.length]?
скакун
Пример с патчами для обезьян довольно неприхотлив в этом вопросе, это просто неуместное и уродливое ИМО.
Дредозубов
3
Спасибо @ the-tin-man за сбор данных!
Увы, мне не очень нравятся эти решения. Либо они требуют дополнительного шага для получения результата ( [0] = '', .strip!), либо они не очень семантически / не понимают, что происходит ( [1..-1]: «Гм, диапазон от 1 до отрицательного 1? Yearg?»), Или они медленны или длинны до выпиши ( .gsub, .length).
То, что мы пытаемся сделать, это «сдвиг» (на языке Array), но возвращающий оставшиеся символы, а не то, что было смещено. Давайте использовать наш Ruby, чтобы сделать это возможным со строками! Мы можем использовать операцию быстрой скобки, но дать ей хорошее имя и взять аргумент, чтобы указать, сколько мы хотим сжать с фронта:
Но есть еще кое-что, что мы можем сделать с помощью этой быстрой, но громоздкой операции с брекетами. Пока мы это делаем, для полноты давайте напишем a #shiftи #firstдля String (почему Array должен быть всем забавным), взяв аргумент arg, чтобы указать, сколько символов мы хотим удалить с самого начала:
classStringdef first(how_many =1)self[0...how_many]enddef shift(how_many =1)
shifted = first(how_many)self.replace self[how_many..-1]
shifted
end
alias_method :shift!,:shift
end
Хорошо, теперь у нас есть хороший четкий способ вытаскивания символов с начала строки с помощью метода, который соответствует Array#firstи Array#shift(который действительно должен быть методом взрыва ??). И мы можем легко получить измененную строку с помощью #eat!. Хм, мы должны поделиться нашей новой eat!силой с массивом? Почему нет!
delete_prefix
иdelete_prefix!
- подробнее ниже . У меня не было времени на тесты, но скоро сделаю!delete_prefix
\delete_prefix!
), и они довольно быстрые. Не совсем удачные предыдущие фавориты по скорости, но читабельность означает, что у них есть отличные новые возможности!Ответы:
Я предпочитаю использовать что-то вроде:
Я всегда ищу самый быстрый и самый читаемый способ делать вещи:
Запуск на моем Mac Pro:
Обновление, чтобы включить еще один предложенный ответ:
Что приводит к:
И еще одно использование,
/^./
чтобы найти первого персонажа:Что приводит к:
Вот еще одно обновление более быстрого оборудования и более новой версии Ruby:
После выполнения поиска / замены
gsub
необходимо проверить наличие возможных дополнительных совпадений, прежде чем он сможет определить, завершено ли оно.sub
только делает один и заканчивает. Считайте,gsub
что это как минимум дваsub
звонка.Кроме того, важно помнить об этом
gsub
, аsub
также может быть затруднен плохо написанным регулярным выражением, которое сопоставляется гораздо медленнее, чем поиск по подстроке. Если возможно, закрепите регулярное выражение, чтобы получить от него максимальную скорость. Здесь есть ответы на Stack Overflow, демонстрирующие это, поэтому ищите, если вам нужно больше информации.источник
"[12,23,987,43".delete "["
what about "[12,23,987,43".shift ?
"? Как насчет"[12,23,987,43".shift NoMethodError: undefined method
shift 'для "[12,23,987,43": String`?Аналогично ответу Пабло выше, но очиститель тени:
Вернет массив от 1 до последнего символа.
источник
str[1,]
сравнению с вышеупомянутым?str[1,]
вернуть вам 2-й символ, поскольку диапазон1:nil
. Вам нужно будетstr[1,999999]
указать фактическую вычисленную длину или что-то, что гарантированно будет больше длины, например, (используйте, конечно, int_max), чтобы получить весь хвост.[1..-1]
это чище и, вероятно, быстрее, так как вам не нужно работать с длиной вручную (см. [1..length] в тесте производительности)str[1..-2]
Мы можем использовать ломтик, чтобы сделать это:
Используя
slice!
мы можем удалить любой символ, указав его индекс.источник
slice!(0)
ответ действительно должен быть выбран, так как использованиеasdf[0] = ''
для удаления первого символа смешно (так же, как использование gsub с регулярным выражением и стрельба по мухе с помощью гаубицы).[]=
но не требует столько базового кода C, гдеslice!
требуется дополнительная работа. Это добавляет. Аргумент может быть «Что более читабельно?» Я нахожу использование[]=
читабельным, но я исхожу из фона C -> Perl, который, вероятно, окрашивает мое мышление. Разработчики Java, вероятно, подумают, что это менее читабельно. Любой из них является приемлемым способом решения этой задачи, если он прост в понимании и обслуживании и не требует чрезмерной загрузки ЦП.Ruby 2.5+
Начиная с Ruby 2.5 вы можете использовать
delete_prefix
илиdelete_prefix!
для достижения этого в удобочитаемой форме.В этом случае
"[12,23,987,43".delete_prefix("[")
.Больше информации здесь:
Официальные документы
https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/
https://bugs.ruby-lang.org/issues/12694
Примечание: вы также можете использовать это для удаления элементов из конца строки с помощью
delete_suffix
иdelete_suffix!
Редактировать:
Используя настройку Tin Man, он тоже выглядит довольно быстро (под двумя последними записями
delete_p
иdelete_p!
). Не совсем уместен предыдущий фаворит для скорости, хотя очень читабелен.источник
Я предпочитаю это:
источник
Если вы всегда хотите снять ведущие скобки:
Если вы просто хотите удалить первый символ и знаете, что его не будет в многобайтовом наборе символов:
или
источник
"[12,23,987,43".sub(/^\[+/, "")
вместоgsub(/^\[/, "")
. Первый позволяет механизму регулярных выражений находить все совпадения, затем они заменяются одним действием и приводят к увеличению скорости примерно в 2 раза с Ruby 1.9.3.gsub(/\A\[/, "")
?Неэффективная альтернатива:
источник
Например: a = "Один Два Три"
Таким образом, вы можете удалить один за другим первый символ строки.
источник
Простой способ:
Удивительный способ:
(Примечание: предпочитаю легкий способ :))
источник
"[12,23,987,43".reverse.chop.reverse
Спасибо @ the-tin-man за сбор данных!
Увы, мне не очень нравятся эти решения. Либо они требуют дополнительного шага для получения результата (
[0] = ''
,.strip!
), либо они не очень семантически / не понимают, что происходит ([1..-1]
: «Гм, диапазон от 1 до отрицательного 1? Yearg?»), Или они медленны или длинны до выпиши (.gsub
,.length
).То, что мы пытаемся сделать, это «сдвиг» (на языке Array), но возвращающий оставшиеся символы, а не то, что было смещено. Давайте использовать наш Ruby, чтобы сделать это возможным со строками! Мы можем использовать операцию быстрой скобки, но дать ей хорошее имя и взять аргумент, чтобы указать, сколько мы хотим сжать с фронта:
Но есть еще кое-что, что мы можем сделать с помощью этой быстрой, но громоздкой операции с брекетами. Пока мы это делаем, для полноты давайте напишем a
#shift
и#first
для String (почему Array должен быть всем забавным), взяв аргумент arg, чтобы указать, сколько символов мы хотим удалить с самого начала:Хорошо, теперь у нас есть хороший четкий способ вытаскивания символов с начала строки с помощью метода, который соответствует
Array#first
иArray#shift
(который действительно должен быть методом взрыва ??). И мы можем легко получить измененную строку с помощью#eat!
. Хм, мы должны поделиться нашей новойeat!
силой с массивом? Почему нет!Теперь мы можем:
Так-то лучше!
источник
chip()
вместоchop()
(иchimp()
в качестве аналогаchomp()
).источник
источник
Используя регулярное выражение:
источник
Я нахожу хорошее решение
str.delete(str[0])
для его читабельности, хотя я не могу засвидетельствовать его производительность.источник
List удаляет один или несколько элементов с начала массива, не изменяет массив и возвращает сам массив вместо удаленного элемента.
источник