Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 转换数组_Arrays_Ruby_Hash - Fatal编程技术网

Arrays 转换数组

Arrays 转换数组,arrays,ruby,hash,Arrays,Ruby,Hash,我有一个方法返回一组日期之间的年和月 d = (from..to).map {|d| [ d.year, d.month ] }.uniq 我可以像这样迭代每个元素: d.each do |elm| #For Year puts elm[0] #For Month Number puts elm[1] end 如何更改该方法,以便按如下方式进行迭代,以增强代码的可读性,并通常使其更容易 elm.month_number elm.year 使用类或结构。e、 g YearM

我有一个方法返回一组日期之间的年和月

d = (from..to).map {|d| [ d.year, d.month ] }.uniq
我可以像这样迭代每个元素:

d.each do |elm|
  #For Year
  puts elm[0]

  #For Month Number
  puts elm[1]
end
如何更改该方法,以便按如下方式进行迭代,以增强代码的可读性,并通常使其更容易

elm.month_number
elm.year

使用类或结构。e、 g

YearMonth = Struct.new(:year, :month)
d = (from..to).map{|d| YearMonth.new(d.year, d.month)}.uniq
尽管如此,这并不是一种最佳的方法。考虑这一点:

d = (from.year .. to.year).flat_map { |year|
  from_month = year == from.year ? from.month : 1
  to_month = year == to.year ? to.month : 12
  (from_month..to_month).map { |month| YearMonth.new(year, month) }
}

这避免了创建一个巨大的日期数组,以及另一个由
映射产生的数组,该数组可以连续运行数月(即使没有那么紧凑)。

使用类或结构。e、 g

YearMonth = Struct.new(:year, :month)
d = (from..to).map{|d| YearMonth.new(d.year, d.month)}.uniq
尽管如此,这并不是一种最佳的方法。考虑这一点:

d = (from.year .. to.year).flat_map { |year|
  from_month = year == from.year ? from.month : 1
  to_month = year == to.year ? to.month : 12
  (from_month..to_month).map { |month| YearMonth.new(year, month) }
}

这避免了创建一个巨大的日期数组,以及另一个由
映射产生的数组,并且可以连续运行数月(即使它没有那么紧凑)。

我认为您正在寻找如下所述的数组自动解包:


我认为您正在寻找如下所述的阵列自动解包:


您也可以这样做(创建一个具有
year
month
属性的
CustomDate
类):


您也可以这样做(创建一个具有
year
month
属性的
CustomDate
类):


你所做的是多余的。保持日期元素不变(我假设它们是
date
对象)


你所做的是多余的。保持日期元素不变(我假设它们是
date
对象)


在其他答案中有一些很好的讨论,但是在没有必要的情况下,在每年的365天中迭代仅仅得到12个date对象似乎很愚蠢

不要从
迭代到
,而是从每个月开始计算整数个月,然后在该范围内迭代。看一看:

from = Date.civil(2013, 7, 1)
to = Date.civil(2015, 11, 23)

from_mos = 12 * from.year + from.month - 1
to_mos = 12 * to.year + to.month - 1

dates = (from_mos..to_mos).map do |mos|
  year, month = mos.divmod(12)
  Date.civil(year, month + 1, 1)
end
现在,
日期
是一个可枚举的日期,产生每个月的第一天的日期,即2013-07-01、2013-08-01、…2015-11-01,您可以如下使用

dates.each do |date|
  puts "Year #{date.year}, month #{date.month}"
end
# => Year 2013, month 7
#    Year 2013, month 8
#    ...
#    Year 2015, month 10
#    Year 2015, month 11
另外,如果您想麻烦地定义一个类或结构,我建议您直接使用范围API:

YearMonth = Struct.new(:year, :month) do
  def succ
    next_year, next_month = months.succ.divmod(12)
    self.class.new(next_year, next_month + 1)
  end

  def <=>(other)
    months <=> other.months
  end

  protected
  def months
    12 * year + month - 1
  end
end

在其他答案中有一些很好的讨论,但是在没有必要的情况下,在每年的365天中迭代仅仅得到12个date对象似乎很愚蠢

不要从
迭代到
,而是从每个月开始计算整数个月,然后在该范围内迭代。看一看:

from = Date.civil(2013, 7, 1)
to = Date.civil(2015, 11, 23)

from_mos = 12 * from.year + from.month - 1
to_mos = 12 * to.year + to.month - 1

dates = (from_mos..to_mos).map do |mos|
  year, month = mos.divmod(12)
  Date.civil(year, month + 1, 1)
end
现在,
日期
是一个可枚举的日期,产生每个月的第一天的日期,即2013-07-01、2013-08-01、…2015-11-01,您可以如下使用

dates.each do |date|
  puts "Year #{date.year}, month #{date.month}"
end
# => Year 2013, month 7
#    Year 2013, month 8
#    ...
#    Year 2015, month 10
#    Year 2015, month 11
另外,如果您想麻烦地定义一个类或结构,我建议您直接使用范围API:

YearMonth = Struct.new(:year, :month) do
  def succ
    next_year, next_month = months.succ.divmod(12)
    self.class.new(next_year, next_month + 1)
  end

  def <=>(other)
    months <=> other.months
  end

  protected
  def months
    12 * year + month - 1
  end
end

这不是OP要求的,而是推荐的方式。您的意思是OP要求
elm.month
,而这种方式只使用
month
?如果是这样的话,我会说你在技术上是对的,但这真的是一个显著的区别吗?是否有任何理由选择
elm.month
而不是
month
?这正是我所需要的,谢谢!也许我对这个问题不是很清楚。道歉that@sawa在我之后回答,我实际上认为他的解决方案明显更好,因为它更干净,更不迂回。这不是OP要求的,而是推荐的方式。你的意思是OP要求
elm.month
,而这种方式只使用
month
?如果是这样的话,我会说你在技术上是对的,但这真的是一个显著的区别吗?是否有任何理由选择
elm.month
而不是
month
?这正是我所需要的,谢谢!也许我对这个问题不是很清楚。道歉that@sawa在我之后回答,我实际上认为他的解决方案明显更好,因为它更干净,更不迂回。这不是每天都会出现,不是每个月都会出现吗?我正试图让它发挥作用,因为我同意你的观点,它似乎没有我的解决方案那么迂回。但是我无法让它工作:使用
from
to
作为日期对象,我得到了范围
的未定义方法uniq。通过一些谷歌搜索,看起来
Range#map
(就像使用的OP)是唯一的方法<代码>范围#到_a
返回一个空集。我错过了什么吗?对不起,我错过了
到a
(Date.new(2015,11,1)…Date.new(2015,5,1))。到a
返回
[]
…?哈哈,别介意,我,那应该是从
2015,5,1
2015,11,1
这不是每天都会返回吗,不是每个月都这样吗?我正努力让它发挥作用,因为我同意你的观点,它似乎没有我的解决方案那么迂回。但是我无法让它工作:使用
from
to
作为日期对象,我得到了范围
的未定义方法uniq。通过一些谷歌搜索,看起来
Range#map
(就像使用的OP)是唯一的方法<代码>范围#到_a
返回一个空集。我遗漏了什么吗?对不起,我遗漏了
到a
(Date.new(2015,11,1)…Date.new(2015,5,1))。到a
返回
[]
…?哈哈,别介意,我,那应该是从
2015,5,1
2015,11,1