将基于字符串的分钟和秒值相加
Adding together string-based minutes and seconds values
我有一个具有持续时间属性的 Track
模型。该属性基于字符串,并以 minutes:seconds
格式读取。我想知道获取这些基于字符串的值并将它们加在一起的最佳方法是什么。例如,如果有这样的持续时间值:
Duration 1: "1:00"
Duration 2: "1:30"
我怎样才能让它输出 "2:30"
?
我发现的大多数与此问题相关的问题都以基于整数的值开头。完成这项工作的最佳方法是什么?
我的建议是store/manipulate他们作为秒。
将它们存储为整数秒绝对更容易,并将函数应用于 parse/format 将值转换为正确的字符串表示形式。
将它们存储为整数将使它们的求和和减法变得非常容易。
我只是不得不在最近的项目中实现类似的东西。这是一个简单的开始。如果您确定您将始终采用这种格式 'H:S',则无需将持续时间转换为时间对象:
entries = ["01:00", "1:30", "1:45"]
hours = 0
minutes = 0
entries.each do |e|
entry_hours, entry_minutes = e.split(':', 2)
hours += entry_hours.to_i
minutes += entry_minutes.to_i
end
hours += (minutes/60)
minutes = (minutes%60)
p "#{hours}:#{minutes}"
#=> "4:15"
这是可以做到的一种方法:
class Track
attr_accessor :duration
def initialize(duration)
@duration = duration
end
end
arr = [Track.new("1:00"), Track.new("1:30")]
total_seconds = arr.reduce(0) do |a, i|
min, sec = i.duration.split(":").map(&:to_i)
a + min * 60 + sec
end
p total_duration = '%d:%02d' % total_seconds.divmod(60)
#=> "2:30"
我同意@SimoneCarletti:将它们存储为整数秒。但是,您可以将它们包装在持续时间值 class 中,该值可以将自身输出为格式良好的字符串。
class Duration
attr_accessor :seconds
def initialize(string)
minutes, seconds = string.split(':', 2)
@seconds = minutes.to_i * 60 + seconds.to_i
end
def to_s
sprintf("%d:%02d", @seconds / 60, @seconds % 60)
end
def self.sum(*durations)
Duration.new(durations.reduce(0) { |t,d| t + d.seconds })
end
end
编辑:添加了类似于下面@CarySwoveland 建议的求和方法。您可以按如下方式使用它:
durations = ["1:30", "2:15"].map { |str| Duration.new(str) }
total = Duration.sum *durations
编辑:我错过了@Wand 之前的回答,它和我的一样。我将离开我的计算方式。
arr = %w| 1:30 3:07 12:53 |
#=> ["1:30", "3:07", "12:53"]
"%d:%2d" % arr.reduce(0) do |tot,str|
m,s = str.split(':')
tot + 60*m.to_i + s.to_i
end.divmod(60)
#=> "17:30"
我有一个具有持续时间属性的 Track
模型。该属性基于字符串,并以 minutes:seconds
格式读取。我想知道获取这些基于字符串的值并将它们加在一起的最佳方法是什么。例如,如果有这样的持续时间值:
Duration 1: "1:00"
Duration 2: "1:30"
我怎样才能让它输出 "2:30"
?
我发现的大多数与此问题相关的问题都以基于整数的值开头。完成这项工作的最佳方法是什么?
我的建议是store/manipulate他们作为秒。
将它们存储为整数秒绝对更容易,并将函数应用于 parse/format 将值转换为正确的字符串表示形式。
将它们存储为整数将使它们的求和和减法变得非常容易。
我只是不得不在最近的项目中实现类似的东西。这是一个简单的开始。如果您确定您将始终采用这种格式 'H:S',则无需将持续时间转换为时间对象:
entries = ["01:00", "1:30", "1:45"]
hours = 0
minutes = 0
entries.each do |e|
entry_hours, entry_minutes = e.split(':', 2)
hours += entry_hours.to_i
minutes += entry_minutes.to_i
end
hours += (minutes/60)
minutes = (minutes%60)
p "#{hours}:#{minutes}"
#=> "4:15"
这是可以做到的一种方法:
class Track
attr_accessor :duration
def initialize(duration)
@duration = duration
end
end
arr = [Track.new("1:00"), Track.new("1:30")]
total_seconds = arr.reduce(0) do |a, i|
min, sec = i.duration.split(":").map(&:to_i)
a + min * 60 + sec
end
p total_duration = '%d:%02d' % total_seconds.divmod(60)
#=> "2:30"
我同意@SimoneCarletti:将它们存储为整数秒。但是,您可以将它们包装在持续时间值 class 中,该值可以将自身输出为格式良好的字符串。
class Duration
attr_accessor :seconds
def initialize(string)
minutes, seconds = string.split(':', 2)
@seconds = minutes.to_i * 60 + seconds.to_i
end
def to_s
sprintf("%d:%02d", @seconds / 60, @seconds % 60)
end
def self.sum(*durations)
Duration.new(durations.reduce(0) { |t,d| t + d.seconds })
end
end
编辑:添加了类似于下面@CarySwoveland 建议的求和方法。您可以按如下方式使用它:
durations = ["1:30", "2:15"].map { |str| Duration.new(str) }
total = Duration.sum *durations
编辑:我错过了@Wand 之前的回答,它和我的一样。我将离开我的计算方式。
arr = %w| 1:30 3:07 12:53 |
#=> ["1:30", "3:07", "12:53"]
"%d:%2d" % arr.reduce(0) do |tot,str|
m,s = str.split(':')
tot + 60*m.to_i + s.to_i
end.divmod(60)
#=> "17:30"