如何在Ruby中简化将多个值推送到数组中?

时间:2014-05-01 05:22:53

标签: ruby-on-rails ruby arrays

你会如何改进:

time = Time.now
    @time = []
    @time.push(
               (time-1.week).strftime("%m-%d"),
               (time-6.days).strftime("%m-%d"),
               (time-5.days).strftime("%m-%d"),
               (time-4.days).strftime("%m-%d"),
               (time-3.days).strftime("%m-%d"),
               (time-2.days).strftime("%m-%d"),
               (time-1.day).strftime("%m-%d"),
               (time).strftime("%m-%d")
              )

我尝试了以下一些建议:

time = Time.now
    iterations = 1000
    Benchmark.bm do |bm|
      bm.report do
         iterations.times do
            @time = 7.downto(0).map { |v| (time - v.days).strftime("%m-%d") }
          end
      end
      bm.report do
       iterations.times do
          @time = []
          @time.push(
               (time-1.week).strftime("%m-%d"),
               (time-6.days).strftime("%m-%d"),
               (time-5.days).strftime("%m-%d"),
               (time-4.days).strftime("%m-%d"),
               (time-3.days).strftime("%m-%d"),
               (time-2.days).strftime("%m-%d"),
               (time-1.day).strftime("%m-%d"),
               (time).strftime("%m-%d")
              )
       end
      end
     end

       user     system      total        real
   0.350000   0.960000   1.310000 (  1.310054)
   0.310000   0.840000   1.150000 (  1.156484)

downto明显慢于我的方法。

下一个测试使用了该方法:

@time = (0..7).map { |x| (time - x.days).strftime("%m-%d") }.reverse

1000次迭代

       user     system      total        real
   0.340000   0.980000   1.320000 (  1.321518)
   0.300000   0.840000   1.140000 (  1.149759)

5000次迭代

       user     system      total        real
   1.720000   4.800000   6.520000 (  6.545335)
   1.530000   4.180000   5.710000 (  5.712035)

我很难在没有同时看到Ruby核心的downto和地图的情况下绕过它,但在这两种情况下,我更加细长的编写方法响应速度比简化方法更快(我喜欢从可读性的角度来看,下面的答案更多。如果我做错了,请详细说明我的测试。我希望地图可以让我远离水面。

更新了STEFAN&S;答案

所以我在下面看到Stefan的答案并将其扔进测试人员:

       user     system      total        real
   0.040000   0.000000   0.040000 (  0.035976)
   1.520000   4.180000   5.700000 (  5.704401)

神圣的废话! 5000次迭代,它绝对会破坏我的方法。

因为他准确地指出我只对Dates感兴趣,所以我决定将自己的方法从Time.now改为Date.today并测试它:

       user     system      total        real
   0.090000   0.000000   0.090000 (  0.085940)
   0.390000   0.000000   0.390000 (  0.398143)

有点奇怪的是,在第一次测试中,Stefan的方法在0.0359时钟,在第二个时钟在0.0859,超过两倍,但它仍然是百分之五秒以上5000迭代 - 所以我认为我在这里深入分裂头发领域。

尽管如此 - 斯特凡的方式抹杀了我自己的方法 - 所以我给了他复选标记。

4 个答案:

答案 0 :(得分:3)

您可以使用#downto -

执行以下操作
time = Time.now
@time = 7.downto(0).map {|v| (time - v.days).strftime("%m-%d") }

答案 1 :(得分:1)

你可以使用不推送自己,但是收集,即Range从零到七的组合,以及Array的{​​{3}}方法:

time = Time.now
@time = (0..7).map {|v| (time - v.days).strftime("%m-%d") }.reverse
# => ["04-24", "04-25", "04-26", "04-27", "04-28", "04-29", "04-30", "05-01"]

答案 2 :(得分:1)

我会使用Array#map方法

来编写它
time = Time.now
@time = (0..7).map { |x| (time - x.days).strftime("%m-%d") }.reverse

答案 3 :(得分:1)

由于您只对日期感兴趣,因此您可以使用RangeDate个实例(日期increment in 1-day steps):

today = Date.today
(today-7..today).map { |date| date.strftime("%m-%d") }
#=> ["04-24", "04-25", "04-26", "04-27", "04-28", "04-29", "04-30", "05-01"]