在Ruby中连接同一数组中的现有值

时间:2017-01-06 17:03:20

标签: arrays ruby

以下是我正在使用的数组示例:

arr = [ "id1", "name1", "id2", "name2", "id3", "name3" ]

我想将其更改为一个新的数组,如下所示:

new_arr = [ "id1: name1", "id2: name2", "id3: name3" ]

我的尝试:

ids = arr.select.with_index { |_, i| i.even? }
names = arr.select.with_index { |_, i| i.odd? }
new_arr = ids.map { |i| i + ": " +  names[ids.index(i)] }

是否有更好或更具表现力的方式(可能是单行)?

5 个答案:

答案 0 :(得分:3)

我会使用each_slice和字符串插值。

arr.each_slice(2).map { |(a, b)| "#{a}: #{b}" }
#=> ["id1: name1", "id2: name2", "id3: name3"]

理查德·汉密尔顿的评论让我想到了不同解决方案的表现:

require 'benchmark'

arr = [ "id1", "name1", "id2", "name2", "id3", "name3" ]
slices = arr.each_slice(2)

n = 1_000_000

Benchmark.bmbm(15) do |x|
  x.report("hashified     :") { n.times do; Hash[*arr].map { |e| e.join ': ' }    ; end }
  x.report("concatenation :") { n.times do; slices.map { |a| a[0] + ": " + a[1] } ; end }
  x.report("array join    :") { n.times do; slices.map { |a| a.join(': ') }       ; end }
  x.report("interpolated  :") { n.times do; slices.map { |(a, b)| "#{a}: #{b}" }  ; end }
end

# Rehearsal ---------------------------------------------------
# hashified     :   3.520000   0.030000   3.550000 (  3.561024)
# concatenation :   2.300000   0.010000   2.310000 (  2.315952)
# array join    :   3.020000   0.010000   3.030000 (  3.032235)
# interpolated  :   1.950000   0.000000   1.950000 (  1.954937)
# ----------------------------------------- total: 10.840000sec
# 
#                       user     system      total        real
# hashified     :   3.430000   0.040000   3.470000 (  3.473274)
# concatenation :   2.320000   0.010000   2.330000 (  2.332920)
# array join    :   3.070000   0.010000   3.080000 (  3.081937)
# interpolated  :   1.950000   0.000000   1.950000 (  1.956998)

答案 1 :(得分:2)

您可以使用Enumerableeach_slice方法从arr获取2元素数组的枚举。然后,您可以简单地join这些元素:

arr.each_slice(2).map{|a| a.join(': ')}

这里发生的是each_slice返回一个Enumerator,它产生了2个元素的数组。由于Enumerator也是Enumerable,因此您可以使用map更改这些2元素数组,并将join更改为字符串。

答案 2 :(得分:2)

each_slice很傻:)

Hash[ "id1", "name1", "id2", "name2", "id3", "name3" ].
  map { |e| e.join ': ' }
#⇒ [ "id1: name1", "id2: name2", "id3: name3" ]

答案 3 :(得分:1)

尝试使用each_slice

arr.each_slice(2).entries.map { |ar| ar.join(': ') }                    
#=> ["id1: name1", "id2: name2", "id3: name3"]

答案 4 :(得分:1)

您应该使用each_slice来实现此目标

arr.each_slice(2).map { |a| a[0] + ": " + a[1] }
=> ["id1: name1", "id2: name2", "id3: name3"]