ruby 1.9 – 什么是`string.codepoints.to_a`的最简单的反转?

ruby 1.9.3中,我可以获得字符串的代码点:
> "foo\u00f6".codepoints.to_a
 => [102,111,246]

有没有内置的方法去另一个方向,即从整数数组到字符串?

我知道:

# not acceptable; only works with UTF-8
[102,246].pack("U*")

# works,but not very elegant
[102,246].inject('') {|s,cp| s << cp }

# concise,but I need to unshift that pesky empty string to "prime" the inject call
['',102,246].inject(:<<)

更新(回应尼克拉斯的回答)

有趣的讨论.
pack(“U *”)始终返回UTF-8字符串,而inject版本返回文件源编码中的字符串.

#!/usr/bin/env ruby
# encoding: iso-8859-1

p [102,246].inject('',:<<).encoding
p [102,246].pack("U*").encoding
# this raises an Encoding::CompatibilityError
[102,246].pack("U*") =~ /\xf6/

对我来说,inject调用返回一个ISO-8859-1字符串,而pack返回一个UTF-8.为了防止错误,我可以使用pack(“U *”).encode(__ ENCODING__),但这使我做了额外的工作.

更新2

显然是字符串#<<根据字符串的编码,并不总是正确追加.因此看起来包装仍然是最好的选择.

[225].inject(''.encode('utf-16be'),:<<)  # fails miserably
[225].pack("U*").encode('utf-16be')  # works

解决方法

你自己的尝试最明显的适应是
[102,:<<)

然而,这不是一个好的解决方案,因为它只有在初始空字符串文字具有能够保存整个Unicode字符范围的编码时才有效.以下失败:

#!/usr/bin/env ruby
# encoding: iso-8859-1
p "\u{1234}".codepoints.to_a.inject('',:<<)

所以我实际上建议

codepoints.pack("U*")

我不知道你的意思是“只适用于UTF-8”.它创建了一个UTF-8编码的Ruby字符串,但UTF-8可以保存整个Unicode字符范围,那么问题是什么呢?注意:

irb(main):010:0> s = [0x33333,0x1ffff].pack("U*")
=> "\u{33333}\u{1FFFF}"
irb(main):011:0> s.encoding
=> #<Encoding:UTF-8>
irb(main):012:0> [0x33333,0x1ffff].pack("U*") == [0x33333,0x1ffff].inject('',:<<)
=> true

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...