Получение и удаление первого символа строки

102

Я хотел бы сделать несколько двумерных прогулок, используя строки символов, присвоив каждому символу разные значения. Я планировал «вытолкнуть» первый символ строки, использовать его и повторить для остальной части строки.

Как я могу добиться чего-то подобного?

x <- 'hello stackoverflow'

Я бы хотел сделать что-то вроде этого:

a <- x.pop[1]

print(a)

'h'
print(x)

'ello stackoverflow'
Pedrosaurio
источник

Ответы:

168

Смотрите ?substring.

x <- 'hello stackoverflow'
substring(x, 1, 1)
## [1] "h"
substring(x, 2)
## [1] "ello stackoverflow"

Идея наличия popметода, который возвращает значение и имеет побочный эффект обновления данных, хранящихся в, во xмногом является концепцией объектно-ориентированного программирования. Поэтому вместо того, чтобы определять popфункцию для работы с векторами символов, мы можем создать ссылочный класс с popметодом.

PopStringFactory <- setRefClass(
  "PopString",
  fields = list(
    x = "character"  
  ),
  methods = list(
    initialize = function(x)
    {
      x <<- x
    },
    pop = function(n = 1)
    {
      if(nchar(x) == 0)
      {
        warning("Nothing to pop.")
        return("")
      }
      first <- substring(x, 1, n)
      x <<- substring(x, n + 1)
      first
    }
  )
)

x <- PopStringFactory$new("hello stackoverflow")
x
## Reference class object of class "PopString"
## Field "x":
## [1] "hello stackoverflow"
replicate(nchar(x$x), x$pop())
## [1] "h" "e" "l" "l" "o" " " "s" "t" "a" "c" "k" "o" "v" "e" "r" "f" "l" "o" "w"
Ричи Коттон
источник
15

Также есть str_subиз пакета stringr

x <- 'hello stackoverflow'
str_sub(x, 2) # or
str_sub(x, 2, str_length(x))
[1] "ello stackoverflow"
Тони Ладсон
источник
10

Используйте эту функцию из stringiпакета

> x <- 'hello stackoverflow'
> stri_sub(x,2)
[1] "ello stackoverflow"
бартектартанус
источник
8

substringопределенно лучший, но вот одна strsplitальтернатива, так как я ее еще не видел.

> x <- 'hello stackoverflow'
> strsplit(x, '')[[1]][1]
## [1] "h"

или эквивалентно

> unlist(strsplit(x, ''))[1]
## [1] "h"

А pasteоставшуюся часть веревки можно снова собрать.

> paste0(strsplit(x, '')[[1]][-1], collapse = '')
## [1] "ello stackoverflow"
Rich Scriven
источник
5

удаление первых символов:

x <- 'hello stackoverflow'
substring(x, 2, nchar(x))

Идея состоит в том, чтобы выбрать все символы от 2 до количества символов в x. Это важно, когда у вас неравное количество символов в слове или фразе.

Выбор первой буквы тривиален, как и предыдущие ответы:

substring(x,1,1)
Джон
источник
2

Другой альтернативой является использование захвата подвыражений с функциями регулярного выражения regmatchesи regexec.

# the original example
x <- 'hello stackoverflow'

# grab the substrings
myStrings <- regmatches(x, regexec('(^.)(.*)', x))

Это возвращает всю строку, первый символ и "вытянутый" результат в виде списка длиной 1.

myStrings
[[1]]
[1] "hello stackoverflow" "h"                   "ello stackoverflow" 

что эквивалентно list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))). То есть он содержит супернабор желаемых элементов, а также полную строку.


Добавление sapplyпозволит этому методу работать для вектора символов длиной> 1.

# a slightly more interesting example
xx <- c('hello stackoverflow', 'right back', 'at yah')

# grab the substrings
myStrings <- regmatches(x, regexec('(^.)(.*)', xx))

Это возвращает список с совпавшей полной строкой в ​​качестве первого элемента и совпадающими подвыражениями, захваченными в ()качестве следующих элементов. Таким образом , в регулярном выражении '(^.)(.*)', (^.)соответствует первому символу и (.*)соответствует оставшиеся символы.

myStrings
[[1]]
[1] "hello stackoverflow" "h"                   "ello stackoverflow" 

[[2]]
[1] "right back" "r"          "ight back" 

[[3]]
[1] "at yah" "a"      "t yah" 

Теперь мы можем использовать метод trusty sapply+ [для извлечения нужных подстрок.

myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back"          "t yah"
lmo
источник
Это очень хороший трюк, но я думаю, что упускает из виду вопрос.
pedrosaurio
Вам нужно будет объяснить дальше, поскольку он может дать тот же результат, что и другие ответы. См. Последний блок кода, который используется sapplyдля извлечения. "выталкивание" первого символа, как указано в вопросе, заключается в повторении этого процесса для результирующего вектора (mySecondStrings).
lmo
Конечно, это работает с дополнительным объяснением, которое вы только что добавили, но я все же считаю его более запутанным, чем следовало бы.
pedrosaurio