2016-06-14 14 views
7

Tôi đã làm việc với các phương thức Ruby chrord gần đây và có một vài điều tôi không hiểu.Cố gắng hiểu các phương thức Ruby .chr và .ord

Dự án hiện tại của tôi liên quan đến việc chuyển đổi các ký tự riêng lẻ sang và từ các giá trị thứ tự. Như tôi đã hiểu, nếu tôi có một chuỗi ký tự riêng lẻ như "A" và tôi gọi ord trên đó, tôi nhận được vị trí của nó trên bảng ASCII là 65. Gọi ngược, 65.chr cho tôi giá trị ký tự "A", do đó, điều này cho tôi biết rằng Ruby có một bộ sưu tập ở đâu đó có giá trị ký tự đặt hàng và có thể sử dụng bộ sưu tập này để cho tôi vị trí của một nhân vật cụ thể hoặc nhân vật ở một vị trí cụ thể. Tôi có thể sai về điều này, xin vui lòng sửa tôi nếu tôi.

Bây giờ tôi cũng hiểu rằng mã hóa ký tự mặc định của Ruby sử dụng UTF-8 để nó có thể hoạt động với hàng nghìn ký tự có thể. Vì vậy, nếu tôi hỏi nó cho một cái gì đó như thế này:

'好'.ord 

tôi có được vị trí của nhân vật đó là 22909. Tuy nhiên, nếu tôi gọi chr trên giá trị đó:

22909.chr 

tôi nhận được "RangeError: 22909 ra khỏi phạm vi char. " Tôi chỉ có thể nhận được char để làm việc trên các giá trị tối đa 255 được mở rộng ASCII. Vì vậy, câu hỏi của tôi là:

  • Tại sao của Ruby dường như là việc giá trị cho chr từ ký tự ASCII mở rộng thiết lập nhưng ord từ UTF-8?
  • Có cách nào để yêu cầu Ruby sử dụng các mã hóa khác nhau khi sử dụng các phương pháp này không? Ví dụ, nói với nó để sử dụng mã hóa ASCII-8BIT thay vì bất cứ điều gì nó mặc định?
  • Nếu có thể thay đổi mã hóa mặc định, có cách nào để nhận tổng số ký tự có sẵn trong tập hợp đang được sử dụng không?
+6

http://apidock.com/ruby/Integer/chr đề cập đến bạn có thể sử dụng một cái gì đó như '' 22909.chr (Encoding :: UTF_8) ''. Mã hóa cũng có '' Encoding :: ASCII_8BIT'' nếu bạn muốn sử dụng nó thay thế. –

+0

@NabeelAmjad Bạn nên đăng câu trả lời đó. –

+0

Điều này là rất hữu ích, tôi đã không nhìn thấy điều đó và điều này giúp tôi có được một chặng đường dài đến nơi tôi đang đi. Bây giờ, điều duy nhất tôi đang thiếu là một cách đơn giản để có được số ký tự sẵn có cho một mã hóa cụ thể. Ví dụ ASCII_8BIT có 256 ký tự, UTF_8 khoảng 1.1 triệu, ect. Và có, xin vui lòng gửi nó như là một câu trả lời. –

Trả lời

3

Theo Integer#chr bạn có thể sử dụng phần sau để buộc mã hóa là UTF_8.

22909.chr(Encoding::UTF_8) 
#=> "好" 

Để liệt kê tất cả các tên mã hóa có sẵn

Encoding.name_list 
#=> ["ASCII-8BIT", "UTF-8", "US-ASCII", "UTF-16BE", "UTF-16LE", "UTF-32BE", "UTF-32LE", "UTF-16", "UTF-32", ...] 

Một cách hacky để có được số lượng ký tự tối đa

2000000.times.reduce(0) do |x, i| 
    begin 
    i.chr(Encoding::UTF_8) 
    x += 1 
    rescue 
    end 

    x 
end 
#=> 1112064 
+0

Rất đẹp, cảm ơn bạn. Tôi sợ tôi phải thử một thứ như thế để lấy số ký tự tối đa. Không đẹp, nhưng chúng tôi làm việc với những gì chúng tôi có, phải không? Cổ vũ giao phối. –

0

Sau khi dụng cụ xung quanh với điều này trong một thời gian, tôi nhận ra rằng tôi có thể nhận được số ký tự tối đa cho mỗi mã hóa bằng cách chạy tìm kiếm nhị phân để tìm giá trị cao nhất không ném ra một RangeError.

def get_highest_value(set) 
    max = 10000000000 
    min = 0 
    guess = 5000000000 

    while true 
    begin guess.chr(set) 
     if (min > max) 
     return max 
     else 
     min = guess + 1 
     guess = (max + min)/2 
     end 
    rescue 
     if min > max 
     return max 
     else 
     max = guess - 1 
     guess = (max + min)/2 
     end 
    end 
    end 
end 

Giá trị được nạp cho phương thức là tên của mã hóa đang được chọn.

Các vấn đề liên quan