อะไรคือสิ่งที่ตรงกันข้ามกับ chr () ใน Ruby?


100

ในหลายภาษามีคู่ของฟังก์ชั่นchr()และord()ซึ่งแปลงระหว่างตัวเลขและตัวอักษรค่า ในบางภาษาที่เรียกว่าord()asc()

Ruby มีInteger#chrซึ่งใช้งานได้ดี:

>> 65.chr
A

พอใช้. แต่คุณจะไปทางอื่นได้อย่างไร?

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

พิมพ์:

65

และนั่นก็ค่อนข้างใกล้เคียงกับที่ฉันต้องการ แต่ฉันอยากจะหลีกเลี่ยงการวนซ้ำจริงๆ - ฉันกำลังมองหาสิ่งที่สั้นพอที่จะอ่านได้เมื่อประกาศกconst.

คำตอบ:



33

ใน Ruby จนถึงและรวมถึงซีรีส์ 1.8 สิ่งต่อไปนี้จะสร้าง 65 (สำหรับ ASCII):

puts ?A
'A'[0]

พฤติกรรมเปลี่ยนไปใน Ruby 1.9 ทั้งสองอย่างข้างต้นจะสร้าง "A" แทน วิธีที่ถูกต้องในการทำสิ่งนี้ใน Ruby 1.9 คือ:

'A'[0].ord

น่าเสียดายที่ordวิธีนี้ไม่มีอยู่ใน Ruby 1.8


โชคไม่ดีที่วิธีที่ "ถูกต้อง" ใน Ruby 1.9 นั้นยาวมาก แต่อย่างน้อยก็จะแสดงง่ายขึ้นในการค้นหา "ord" ขอบคุณสำหรับคำตอบโดยละเอียด
RJHunter

13

ลอง:

'A'.unpack('c')

1
ตอนนี้ Ruby 1.9 ได้เปลี่ยนความหมายของ 'A' [0] แล้วนี่เป็นวิธีที่พกพาสะดวกกว่า
AShelly

10

ฉันต้องการ +1 ความคิดเห็นของ dylanfm และ AShelly แต่เพิ่ม [0]:

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

การเรียก unpack จะส่งคืน Array ที่มีจำนวนเต็มเดียวซึ่งไม่ได้รับการยอมรับเสมอไปในกรณีที่ต้องการจำนวนเต็ม:

$ ruby ​​-e 'printf ("0x% 02X \ n", "A" .unpack ("C"))'
-e: 1: ใน `` printf ': ไม่สามารถแปลง Array เป็น Integer (TypeError)
    จาก -e: 1
$ ruby ​​-e 'printf ("0x% 02X \ n", "A" .unpack ("C") [0])'
0x41
$ 

ฉันพยายามเขียนโค้ดที่ใช้ได้กับ Ruby 1.8.1, 1.8.7 และ 1.9.2

แก้ไขเพื่อส่งผ่าน C เพื่อแกะเป็นตัวพิมพ์ใหญ่เนื่องจากการแกะ ("c") ให้ -1 โดยที่ ord () ให้ฉัน 255 (แม้ว่าจะทำงานบนแพลตฟอร์มที่มีการลงนาม char ของ C)


4

เพิ่งเจอสิ่งนี้ในขณะที่รวบรวม Stringprep เวอร์ชัน Ruby แท้ผ่าน RFCs

ระวังความchrล้มเหลวภายนอก [0,255] ให้ใช้ 1.9.x - 2.1.x แทนแบบพกพา:

[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)>

ขอบคุณดูเหมือนว่านี่จะเป็นคำตอบเดียวที่ให้charและผกผันในกรณีของ Unicode อย่างถูกต้อง
Munyari





0

ฉันกำลังเขียนโค้ดสำหรับ 1.8.6 และ 1.9.3 และฉันไม่สามารถรับโซลูชันใด ๆ เหล่านี้เพื่อทำงานในทั้งสองสภาพแวดล้อม :(

อย่างไรก็ตามฉันเจอวิธีอื่น: http://smajnr.net/2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html

นั่นไม่ได้ผลสำหรับฉัน แต่ฉันปรับให้เหมาะกับการใช้งานของฉัน:

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

เมื่อทำเช่นนั้นสิ่งต่อไปนี้จะใช้ได้กับทั้งสองสภาพแวดล้อม

'A'[0].ord


เมื่อผู้ใช้ 18096 เขียนคำตอบ"A".unpack("C")[0]นั่นคือกำหนดเป้าหมายไปที่ Ruby 1.8.1, Ruby 1.8.7 และ Ruby 1.9.2 มันล้มเหลวในสภาพแวดล้อมของคุณหรือไม่? ล้มเหลวแบบไหน?
RJHunter

สวัสดี RJHunter ฉันกำลังพยายามแปลงอักขระเฉพาะในสตริงเป็นค่าตัวเลข โค้ดต่อไปนี้ใช้ได้ใน 1.9.3 แต่ไม่ใช่ 1.8.6 self.status = tagAccountString[4].unpack('C')[0] ใน 1.8.6 ฉันได้รับการ Exception undefined method แกะ 'สำหรับ 0: Fixnum ประมวลผลข้อมูลแท็กบัฟเฟอร์หลัก - exit` รหัสต่อไปนี้ใช้งานได้ (กับโซลูชันที่ฉันเสนอ) ในทั้งสองสภาพแวดล้อม self.status = tagAccountString[4].ord คำแนะนำใด ๆ (เช่นโซลูชันที่ดีกว่า) ยินดีเป็นอย่างยิ่ง
hantscolin

tagAccountString[4]ส่งคืนสตริงในรูบี้ที่ใหม่กว่า แต่ใช้เพื่อส่งคืน Fixnum ใน Ruby 1.8 undefined method unpack for 0:Fixnumนั่นเป็นเหตุผลที่คุณเห็นข้อผิดพลาด คุณสามารถใช้status = tagAccountString[4,1].unpack('C')[0]หรือแม้ว่าstatus, = tagAccountString.unpack('xxxxC')คุณต้องการละเว้นอักขระสี่ตัวและแปลงอักขระถัดไป
RJHunter

ขอบคุณ RJHunter สำหรับคำอธิบายและทางเลือกอื่น ๆ อย่างไรก็ตามเนื่องจากโซลูชัน "ของฉัน" สามารถอ่านและใช้ซ้ำได้มากขึ้นฉันจะยึดตามนั้น (เว้นแต่จะมีเหตุผลที่ดีไม่เช่นกัน)
hantscolin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.