Bir dizenin ilk karakterini alma ve kaldırma


102

Her karaktere farklı değerler atayarak karakter dizilerini kullanarak 2 boyutlu yürüyüşler yapmak istiyorum. Bir dizenin ilk karakterini 'patlatmayı', kullanmayı ve dizenin geri kalanı için tekrar etmeyi planlıyordum.

Böyle bir şeyi nasıl başarabilirim?

x <- 'hello stackoverflow'

Bunun gibi bir şey yapabilmek isterim:

a <- x.pop[1]

print(a)

'h'
print(x)

'ello stackoverflow'

Yanıtlar:


168

Bakın ?substring.

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

popHem bir değer döndüren hem de depolanan verileri güncellemenin bir yan etkisi olan bir yönteme sahip olma fikri, xnesne yönelimli programlamadan gelen bir kavramdır. Dolayısıyla pop, karakter vektörleri üzerinde çalışacak bir fonksiyon tanımlamak yerine , bir yöntemle bir referans sınıf yapabiliriz 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

Orada da str_substringr paketinden

x <- 'hello stackoverflow'
str_sub(x, 2) # or
str_sub(x, 2, str_length(x))
[1] "ello stackoverflow"

10

stringiPaketteki bu işlevi kullanın

> x <- 'hello stackoverflow'
> stri_sub(x,2)
[1] "ello stackoverflow"

8

substringkesinlikle en iyisi, ancak strsplithenüz bir tane görmediğim için işte bir alternatif.

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

Veya eşdeğer olarak

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

Ve pasteipin geri kalanını bir araya getirebilirsiniz .

> paste0(strsplit(x, '')[[1]][-1], collapse = '')
## [1] "ello stackoverflow"

5

ilk karakterleri kaldırma:

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

Fikir, 2'den başlayarak x'deki karakter sayısına kadar tüm karakterleri seçmektir. Kelime veya kelime öbeğinde eşit olmayan sayıda karakteriniz olduğunda bu önemlidir.

İlk harfin seçilmesi önceki cevaplar kadar önemsizdir:

substring(x,1,1)

2

Diğer bir alternatif ise, normal ifade işlevleriyle alt ifadelerin yakalanmasını kullanmaktır regmatchesve regexec.

# the original example
x <- 'hello stackoverflow'

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

Bu, tüm dizeyi, ilk karakteri ve "popped" sonucunu 1 uzunluğunda bir liste olarak döndürür.

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

eşdeğer olan list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))). Yani, istenen öğelerin süper kümesini ve tam dizeyi içerir.


Ekleme sapply, bu yöntemin uzunluğu> 1 olan bir karakter vektörü için çalışmasına izin verecektir.

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

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

Bu, ilk öğe olarak eşleşen tam dizeye ()ve aşağıdaki öğeler olarak yakalanan eşleşen alt ifadelere sahip bir liste döndürür . Normal ifadede Yani '(^.)(.*)', (^.)ilk karakterle eşleşir ve (.*)kalan karakterler eşleşir.

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

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

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

Şimdi, istenen alt dizeleri çıkarmak için trusty sapply+ [yöntemini kullanabiliriz.

myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back"          "t yah"

Bu çok güzel bir numara ama bence bu soruyu kaçırıyor.
pedrosaurio

Diğer cevaplarla aynı çıktıyı üretebileceği için daha fazla açıklamanız gerekecek. sapplyAyıklama için kullanılan son kod bloğuna bakın . Soruda belirtildiği gibi ilk karakteri "patlatmak", bu işlemin sonuç vektöründe (mySecondStrings) tekrarlanması meselesidir.
lmo

Elbette, eklediğiniz ekstra açıklamayla işe yarıyor, ancak yine de olması gerekenden daha karmaşık buluyorum.
pedrosaurio
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.