Ruby'de chr () 'nin tersi nedir?


100

Birçok dilde fonksiyonları, bir çift var chr()ve ord()sayıları ve karakter değerleri arasında dönüşüm. Bazı dillerde ord()denir asc().

Ruby, Integer#chrharika çalışan:

>> 65.chr
A

Yeterince adil. Ama diğer tarafa nasıl gidiyorsun?

"A".each_byte do |byte|
   puts byte
end

baskılar:

65

ve bu istediğime oldukça yakın. Ama gerçekten bir döngüden kaçınmayı tercih ederim - a const.

Yanıtlar:



33

Ruby'de 1.8 serisine kadar ve dahil, aşağıdakilerin her ikisi de 65 üretecektir (ASCII için):

puts ?A
'A'[0]

Ruby 1.9'da davranış değişti, yukarıdakilerin her ikisi de bunun yerine "A" üretecek. Ruby 1.9'da bunu yapmanın doğru yolu şudur:

'A'[0].ord

Ne yazık ki, ordyöntem Ruby 1.8'de mevcut değil.


Ruby 1.9'da "doğru" yolun çok uzun olması talihsiz bir durum, ama en azından "ord" aramalarında daha kolay görünecek. Çok detaylı cevabınız için teşekkürler.
RJHunter

13

Deneyin:

'A'.unpack('c')

1
Ruby 1.9 artık 'A' [0] 'nın anlamını değiştirdiğine göre, bu daha taşınabilir bir yöntemdir.
AShelly

10

Dylanfm ve AShelly'nin yorumunu + 1'lemek istiyorum ancak [0] 'ı eklemek istiyorum:

'A'.unpack('C')[0]

Unpack çağrısı, tek bir tamsayı içeren bir Dizi döndürür ve bu tamsayı istendiğinde her zaman kabul edilmez:

$ ruby ​​-e 'printf ("0x% 02X \ n", "A" .unpack ("C"))'
-e: 1: `` printf '' içinde: Diziyi Tamsayıya (TypeError) dönüştürülemiyor
    -e'den: 1
$ ruby ​​-e 'printf ("0x% 02X \ n", "A" .unpack ("C") [0])'
0x41
$ 

Ruby 1.8.1, 1.8.7 ve 1.9.2'de çalışan bir kod yazmaya çalışıyorum.

Büyük harfle açmak için C'yi geçmek üzere düzenlendi, çünkü unpack ("c") bana -1 verir, burada ord () bana 255 verir (C'nin karakterinin imzalandığı bir platformda çalışmasına rağmen).


4

RFC'ler aracılığıyla Stringprep'in saf bir Ruby versiyonunu bir araya getirirken bununla karşılaştım.

chr[0,255] dışında başarısız olana dikkat edin , bunun yerine 1.9.x - 2.1.x taşınabilir yedekleri kullanın:

[22] pry(main)> "\u0221".ord.chr
RangeError: 545 out of char range
from (pry):2:in 'chr'
[23] pry(main)> x = "\u0221".unpack('U')[0]
=> 545
[24] pry(main)> [x].pack('U')
=> "ȡ"
[25] pry(main)>

Teşekkürler, bu chardoğru unicode durumunda veren ve bunun tersi olan tek cevap gibi görünüyor
Munyari

3

Ek olarak, bir dizede karakteriniz varsa ve onu döngü olmadan çözmek istiyorsanız:

puts 'Az'[0]
=> 65
puts 'Az'[1]
=> 122



2

Değerleri bir diziden çıkarmanın sakıncası yoksa, kullanabilirsiniz "A".bytes


0

1.8.6 ve 1.9.3 için kod yazıyorum ve bu çözümlerden hiçbirinin her iki ortamda da çalışmasını sağlayamadım :(

Ancak başka bir çözümle karşılaştım: http://smajnr.net/2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html

Bu benim için de işe yaramadı ama kendi kullanımım için uyarladım:

unless "".respond_to?(:ord)
  class Fixnum
    def ord
      return self
    end
  end
end

Bunu yaptıktan sonra, aşağıdakiler her iki ortamda da çalışacaktır

'A'[0].ord


User18096 cevabını yazdığında "A".unpack("C")[0], bu Ruby 1.8.1, Ruby 1.8.7 ve Ruby 1.9.2'yi hedefliyordu. Çevrenizde başarısız oluyor mu? Ne tür bir başarısızlık?
RJHunter

Merhaba RJHunter, bir dizedeki belirli bir karakteri sayı değerine dönüştürmeye çalışıyorum. Aşağıdaki kod 1.9.3'te çalışır ancak 1.8.6'da çalışmaz. self.status = tagAccountString[4].unpack('C')[0] 1.8.6'da Exception undefined method '0 için' paketini açıyorum : Fixnum ana arabelleğe alınmış etiket verilerini işliyor - exit` Aşağıdaki kod her iki ortamda da çalışıyor (önerilen çözümümle) self.status = tagAccountString[4].ord Herhangi bir tavsiye (örneğin daha iyi bir çözüm) memnuniyetle karşılanır
hantscolin

tagAccountString[4]Yeni Ruby'de bir String döndürür, ancak Ruby 1.8'de bir Fixnum döndürmek için kullanılır. Bu yüzden hatayı gördün undefined method unpack for 0:Fixnum. Dört karakteri her zaman yok saymak ve bir sonrakini dönüştürmek isteseniz status = tagAccountString[4,1].unpack('C')[0]bile kullanabilirsiniz status, = tagAccountString.unpack('xxxxC').
RJHunter

Açıklama ve alternatif çözümler için RJHunter'a teşekkürler. Ancak, "benim" çözümüm daha okunabilir ve yeniden kullanılabilir olduğu için, buna bağlı kalacağım (iyi bir neden yoksa?)
hantscolin
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.