用于:
a = [ ["John", "Doe"], ["Sue", "Smith"]]
所需输出为:"John Doe, Sue Smith"
暴力代码很简单:
a = [ ["John", "Doe"], ["Sue", "Smith"]]
name_array = []
a.each { |n| name_array << n.join(" ") } # first, inner join w/ space
s = name_array.join(", ") # then, outer join with comma
但是,在Ruby中是否有更简洁的(一行代码?(来实现这一点?
映射并加入
您可以使用Array#map和Array#join来执行此操作。例如,在Ruby 2.7.1:中
array = [["John", "Doe"], ["Sue", "Smith"]]
array.map { _1.join ?s }.join ", "
#=> "John Doe, Sue Smith"
如果你没有使用最新的Ruby,或者发现更明确的语法更可取,你可以做同样的事情:
array.map { |subarray| subarray.join " " }.join ", "
#=> "John Doe, Sue Smith"
当然还有其他方法可以做到这一点,但这一行似乎适合您的示例和用例。
a = [["John", "Doe"], ["Sue", "Smith"], ["Melba", "Jones"]]
其他人提到的显而易见的方法是:
a.map { |arr| arr.join(' ') }.join(', ')
#=> "John Doe, Sue Smith, Melba Jones"
作为练习,这里有三种方法可以在不使用Array#map
的情况下完成
使用可枚举#reduce(又名inject
(
a.drop(1).reduce(a.first.join(' ')) { |s,name| s + ", %s %s" % name }
#=> "John Doe, Sue Smith, Melba Jones"
使用递归
def doit((name, *rest))
rest.empty? ? name.join(' ') : "%s %s, %s" % [*name, doit(rest)]
end
doit(a)
#=> "John Doe, Sue Smith, Melba Jones"
压扁,用空格连接,使用String#gsub插入逗号
r = /
w+[ ]w+ # match two words separated by a space
(?=[ ]) # positive lookahead asserts that next character is a space
K # reset start of match to current location and discard all
# previously matched characters from match that is returned
/x # free-spacing regex definition mode
a.flatten.join(' ').gsub(r, ',')
#=> "John Doe, Sue Smith, Melba Jones"
当您想要从现有数组(或任何可枚举数组(构造新数组时,您真正想要使用的是enumerable#map。
Map在现有数组上迭代,运行块并收集结果。
result = a.map { |people| people.join(' ') }.join(', ')
分解:
intermediate = a.map { |people| people.join(' ') }
# transforms
# [ ["John", "Doe"], ["Sue", "Smith"]]
# into
# [ "John Doe", "Sue Smith" ]
# we take the result of that and run
result = intermediate.join(', ')
# which then transforms your array in the the final string:
# "John Doe, Sue Smith"