Ruby'de bir dizeyi yeni bir dize oluşturmadan kırpmanın standart yolu nedir?


182

Şu an sahip olduğum şey bu - yaptığı iş için çok ayrıntılı görünüyor.

@title        = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil?

Simgelerin, bir CSV satırının bölünmesiyle elde edilen bir dizidir. şimdi şerit gibi fonksiyonları! chomp! ve. dize değiştirilmediyse tüm nil döndürür

"abc".strip!    # => nil
" abc ".strip!  # => "abc"

Kopya oluşturmadan ekstra önde veya arkada boşluklar içeriyorsa, Ruby'yi düzeltmenin en iyi yolu nedir?

Yapmak istersem daha çirkinleşir tokens[Title].chomp!.strip!


3
Tekrar tekrar jetonlardan bir şeyler okuyacaksanız, ön işlem yapmak daha mantıklı olabilir. Yani, "tokens.each {| t | t.strip!}". o zaman sadece "@title = belirteçleri [Başlık] || ''" yapabilirsiniz
glenn mcdonald

Yanıtlar:


272

Sanırım ne istiyorsun:

@title = tokens[Title]
@title.strip!

#strip!Yöntem dönecektir nilbir şey şerit olmasaydı ve o soyuldu eğer değişken kendisi.

Ruby standartlarına göre, ünlem işareti bulunan bir yöntem, değişkeni yerinde değiştirir.

Bu yardımcı olur umarım.

Güncelleme: Bunu göstermek için çıktı irb:

>> @title = "abc"
=> "abc"
>> @title.strip!
=> nil
>> @title
=> "abc"
>> @title = " abc "
=> " abc "
>> @title.strip!
=> "abc"
>> @title
=> "abc"

1
Hmm .. hala düşünüyorum @title = belirteçleri [Başlık] .strip! daha temiz görünüyor - değiştirilmemiş dize yerine nil döndürür yazık. Biri daha iyi bir cevap göndermedikçe .. kabul edilen biti alırsınız.
Gishu

7
@Title = tokens [Title] .strip hile yapacak, ancak bunun yerine bir kopyaya sahip olacaksınız; bu, tokens [Title] değişkenine dokunulmazsa iyi olur.
Igor

9
Ruby 1.9, tam olarak ne istediğinizi yapan bir musluğa sahiptir: @ title.tap {| x | x.strip!}
timkay

2
@timkay Yapmak mümkün @title.tap &:strip!mü? Bu her şeyden daha temiz görünüyor.
Jon Egeland

16
Neden bir nilşey çıkarmazsa dünyada geri dönesin ki? Bu hiç şüphesiz bir ton insanın kafasını karıştırdı (anlamsız olduğu için).
Josh M.

53

BTW, şimdi yakut zaten "!" Olmadan şerit destekler.

Karşılaştırmak:

p "abc".strip! == " abc ".strip!  # false, because "abc".strip! will return nil
p "abc".strip == " abc ".strip    # true

Ayrıca stripkopya olmadan yapmak imkansızdır . String.c'deki kaynaklara bakın:

static VALUE
rb_str_strip(VALUE str)
{
    str = rb_str_dup(str);
    rb_str_strip_bang(str);
    return str;
}

yakut 1.9.3p0 (2011-10-30) [i386-mingw32]

Güncelleme 1: Şimdi gördüğüm gibi - 1999 yılında oluşturuldu (bkz. SVN'de rev # 372 ):

Güncelleme2: strip!kopyalar oluşturmaz - hem 1.9.x, 2.x hem de trunk sürümlerinde.


1
“kopyalar olmadan sıyırmak imkansız” - tabii ki bu mümkün strip!.
Karoly Horvath

@KarolyHorvath 'C ile yazılmış kaynak kodunu görmüyor musunuz? Pls dikkatle okuyun, burada kopyalar hakkında yazdıklarım.
gaRex

1
Tabii ki görüyorum. Ama kaynak kodu bu strip. Bir şeyi yanlış mı anladım? Başka nasıl "kopya olmadan sıyırma imkansız" yorumlayabilirim?
Karoly Horvath

@KarolyHorvath dahili olarak yinelenen her zaman oluşturulur. Bu, `` str = rb_str_dup (str) ''
dizesiyle ilgilidir

1
Ve bir kopya istemiyorsanız, strip!aka kullanırsınız rb_str_strip_bang.
Karoly Horvath

9

Varsayılan kayıt ayırıcısını değiştirmedikçe ve chomping yaptığınız bu olmadığı sürece, şerit sondaki satır başlarını da kaldıracağından hem şerit hem de chomp'a gerek yoktur.

Olly'nin cevabı zaten Ruby'de bunu yapmanın kanonik yoluna sahip, ancak kendinizi çok fazla yaparsanız, bunun için her zaman bir yöntem tanımlayabilirsiniz:

def strip_or_self!(str)
  str.strip! || str
end

Giving:

@title = strip_or_self!(tokens[Title]) if tokens[Title]

Ayrıca @title, belirtecin sıfır olması durumunda if ifadesinin atanmasını engelleyeceğini ve bunun da önceki değerini korumasına neden olacağını unutmayın. Her @titlezaman atanmak istiyorsanız veya sakıncası yoksa , denetimi yönteme taşıyabilir ve çoğaltmayı daha da azaltabilirsiniz:

def strip_or_self!(str)
  str.strip! || str if str
end

Alternatif olarak, kendinizi maceraperest hissediyorsanız, String'in kendisinde bir yöntem tanımlayabilirsiniz:

class String
  def strip_or_self!
    strip! || self
  end
end

Şunlardan birini vermek:

@title = tokens[Title].strip_or_self! if tokens[Title]

@title = tokens[Title] && tokens[Title].strip_or_self!

9

Ruby on Rails kullanıyorsanız bir ezme var

> @title = " abc "
 => " abc " 

> @title.squish
 => "abc"
> @title
 => " abc "

> @title.squish!
 => "abc"
> @title
 => "abc" 

Sadece Ruby kullanıyorsanız strip kullanmak istiyorsunuz

Burada gotcha yatıyor .. senin durumunda patlama patlama olmadan şerit kullanmak istiyorum!

süre şerit! kesinlikle hiçbir eylem olsaydı hala şerit çok şerit güncelleştirir nil döndürür! satır içi kullanılamaz. Şerit satır içi kullanmak istiyorsanız sürümü patlama olmadan kullanabilirsiniz!

şerit! çok hatlı yaklaşım kullanarak

> tokens["Title"] = " abc "
 => " abc "
> tokens["Title"].strip!
 => "abc"
> @title = tokens["Title"]
 => "abc"

şerit tek hat yaklaşım ... SİZİN CEVAP

> tokens["Title"] = " abc "
 => " abc "
> @title = tokens["Title"].strip if tokens["Title"].present?
 => "abc"

4

Bence örneğiniz mantıklı bir yaklaşımdır, ancak bunu biraz basitleştirebilirsiniz:

@title = tokens[Title].strip! || tokens[Title] if tokens[Title]

Alternatif olarak iki satıra koyabilirsiniz:

@title = tokens[Title] || ''
@title.strip!

3

Bunun gibi bir şeye ihtiyaç duyduktan sonra başka bir yöntem kullanmak isterseniz:

( str.strip || str ).split(',')

Bu şekilde soyunup hala bir şeyler yapabilirsiniz :)


1

Benim yolum:

> (@title = " abc ").strip!
 => "abc" 
> @title
 => "abc" 

1

Eğer yakut 1.9 veya aktif desteğiniz varsa, basitçe yapabilirsiniz

@title = tokens[Title].try :tap, &:strip!

Bu gerçekten harika, :tryve:tapBence yakuttaki en güçlü fonksiyonel yapılar olan yöntemi yöntemi kullandığından, bu .

Fonksiyonları tamamen sembol olarak geçiren düz bir şekil:

@title = tokens[Title].send :try, :tap, &:strip!

-1
@title = tokens[Title].strip! || tokens[Title]

Konuyu anlamıyorum tamamen mümkündür, ama bu ihtiyacınız olanı yapmaz mı?

" success ".strip! || "rescue" #=> "success"
"failure".strip! || "rescue" #=> "rescue"
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.