【问题标题】:Manipulate elements of an array by different factors without creating variables for each element通过不同的因素操作数组的元素,而不为每个元素创建变量
【发布时间】:2016-07-18 15:02:50
【问题描述】:

我想通过不同的因素来操作数组的元素,然后对它们求和。

有没有更优雅的方式来编写这段代码:

test = '02:30:09:00'

test2 = test.split(':')

t1 = test2[0].to_i * 3600
t2 = test2[1].to_i * 60
t3 = test2[2].to_i
t4 = test2[3].to_i

dur =  t1 + t2 + t3 + t4

p "#{dur} seconds"

我想知道是否有一种方法可以做到这一点,而无需像我所做的那样为数组的每个元素创建一个变量。

【问题讨论】:

    标签: arrays ruby sum


    【解决方案1】:

    好吧,那就不要创建变量了

    dur = test2[0].to_i * 3600 + test2[1].to_i * 60 + ...
    

    不过,我发现提取具有口语名称的变量通常会提高可读性。关键词是:“说名字”。比较:

    hours_in_secs = time_parts[0].to_i * 3600
    minutes_in_secs = time_parts[1].to_i * 60
    seconds = time_parts[2].to_i
    
    duration_in_seconds = hours_in_secs + minutes_in_secs + seconds
    

    【讨论】:

      【解决方案2】:

      为了提高可读性,请考虑提取方法,例如:

      def seconds_amount(hours, minutes, seconds, cents)
        hours.to_i * 3600 + minutes.to_i * 60 + seconds.to_i + cents.to_f / 100
      end
      
      test = '02:30:09:00'
      test2 = test.split(':')
      puts seconds_amount(*test2)
        # => 9009
      

      Ruby 中的新变量通常不是什么大问题——它不会分配额外的内存,变量只是指向相同对象的指针。

      【讨论】:

      • 谢谢你,我对 ruby​​ 很陌生,这个方法正是我想要的,非常有帮助!
      【解决方案3】:
      '02:30:09:00'.split(":").zip([3600, 60, 1, 1])
      .inject(0){|dur, (s, factor)| dur + s.to_i * factor}
      # => 9009
      

      【讨论】:

      • 以点开头的多行拆分表达式对 IRB 不友好 :)
      【解决方案4】:

      我只是尝试一些 lambda。

      test = '02:30:09:00'
      
      dur = test.split(':').zip([3600, 60, 1, 1]).map(&->(s, i){ s.to_i * i }).inject(:+)
      
      p "#{dur} seconds"
      # => "9009 seconds"
      

      【讨论】:

        【解决方案5】:
        require 'time'
        
        str = '02:30:09:12'
        
        fmt = "%H:%M:%S:%L"
        seconds = DateTime.strptime(str << '0', fmt).to_time -
                  DateTime.strptime("00:00:00:000", fmt).to_time
          #=> 9009.12
        
        • 我假设字符串的最后两个字符("12",我从"00" 更改为使其更有趣)是百分之一秒。 '02:30:09:12' &lt;&lt; '0' #=&gt; "02:30:09:120"12 百分之一秒转换为 120 毫秒。
        • 请参见类方法DateTime::strptime,对于strptime 使用的格式字符串的键,请参见实例方法DateTime#strtime
        • 格式字符串中的"%L" 表示(零填充)毫秒。
        • DateTime.strptime(str &lt;&lt; '0', fmt).to_time 等于自纪元以来的秒数。
        • DateTime.strptime("00:00:00:000", fmt).to_time 等于纪元与前一个午夜之间的秒数。因此,两个 Time 值之间的差异等于自上一个午夜以来经过的秒数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-07
          • 2015-11-09
          • 1970-01-01
          • 2022-11-27
          • 1970-01-01
          • 1970-01-01
          • 2022-01-17
          • 1970-01-01
          相关资源
          最近更新 更多