从数组中删除 nil 值并从引用数组中删除相应的条目
Remove nil values from array and corresponding entries from reference array
我有两个数组生成自:
@dividends_values = @dividends.historical.map(&:dividend).reverse.last(50)
@dividends_dates = @dividends.historical.map(&:date).reverse.last(50)
第一个数组是一个浮点值数组,偶尔会有一些 nil 条目。我想删除那些 nil 条目(这对于紧凑型或类似的东西来说非常容易),但我也想从 @dividends_dates 数组中移动相应的条目。
这是因为日期数组是对值数组的 1-1 引用,所以日期数组的索引 0 对应于值数组的索引 0。
这样做的好方法是什么?
首先,按零过滤。然后将其分成两个数组。
@last_dividends = @dividends.historical.select { |d| d.dividend }
@dividends_values = @last_dividends.map(&:dividend)
@dividends_dates = @last_dividends.map(&:date)
更好的是,将它们变成 [[dividend, date], [...]]
的单个数组
@last_dividends = @dividends
.historical
.select { |d| d.dividend }
.map { |d| [d.dividend, d.date] }
首先让我们创建一个 class-like 对象用于说明。
Dividend = Struct.new(:value, :date)
historical = [
Dividend.new(nil, "Jan 1"),
Dividend.new(10, "Mar 22"),
Dividend.new(13, "Apr 21"),
Dividend.new(nil, "Aug 7"),
Dividend.new(8, "Oct 11")
]
#=> [#<struct Dividend value=nil, dade="Jan 1">,
# #<struct Dividend value=10, date="Mar 22">,
# #<struct Dividend value=13, date="Apr 21">,
# #<struct Dividend value=nil, date="Aug 7">,
# #<struct Dividend value=8, date="Oct 11">]
然后,例如,
inst = historical[3]
#=> #<struct Dividend value=nil, date="Aug 7">
inst.value
#=> nil
inst.date
#=> "Aug 7"
我们可以写
historical.filter_map do |inst|
[inst.value, inst.date] unless inst.value.nil?
end.transpose
#=> [[10, 13, 8], ["Mar 22", "Apr 21", "Oct 11"]]
注意
historical.filter_map do |inst|
[inst.value, inst.date] unless inst.value.nil?
end
#=> [[10, "Mar 22"], [13, "Apr 21"], [8, "Oct 11"]]
如果你有两个具有相应元素的数组,例如:
values = [1, nil, 3]
dates = [Date.new(2022, 5, 1), Date.new(2022, 5, 2), Date.new(2022, 5, 3)]
您可以使用 transpose
:
将它们变成一个 [dividend, date]
对的组合数组
values_with_dates = [values, dates].transpose
#=> [[1, #<Date: 2022-05-01>], [nil, #<Date: 2022-05-02>], [3, #<Date: 2022-05-03>]]
然后您可以通过 reject!
:
删除值为 nil
的元素
values_with_dates.reject! { |value, date| value.nil? }
#=> [[1, #<Date: 2022-05-01>], [3, #<Date: 2022-05-03>]]
然后 transpose
再次将对分开:
values_with_dates.transpose
#=> [[1, 3], [#<Date: 2022-05-01>, #<Date: 2022-05-03>]]
可以使用 Ruby 的 multiple assignment.
将内部数组分配回单独的变量
作为 one-liner:
values, dates = [values, dates].transpose.reject { |v, _| v.nil? }.transpose
我有两个数组生成自:
@dividends_values = @dividends.historical.map(&:dividend).reverse.last(50)
@dividends_dates = @dividends.historical.map(&:date).reverse.last(50)
第一个数组是一个浮点值数组,偶尔会有一些 nil 条目。我想删除那些 nil 条目(这对于紧凑型或类似的东西来说非常容易),但我也想从 @dividends_dates 数组中移动相应的条目。
这是因为日期数组是对值数组的 1-1 引用,所以日期数组的索引 0 对应于值数组的索引 0。
这样做的好方法是什么?
首先,按零过滤。然后将其分成两个数组。
@last_dividends = @dividends.historical.select { |d| d.dividend }
@dividends_values = @last_dividends.map(&:dividend)
@dividends_dates = @last_dividends.map(&:date)
更好的是,将它们变成 [[dividend, date], [...]]
@last_dividends = @dividends
.historical
.select { |d| d.dividend }
.map { |d| [d.dividend, d.date] }
首先让我们创建一个 class-like 对象用于说明。
Dividend = Struct.new(:value, :date)
historical = [
Dividend.new(nil, "Jan 1"),
Dividend.new(10, "Mar 22"),
Dividend.new(13, "Apr 21"),
Dividend.new(nil, "Aug 7"),
Dividend.new(8, "Oct 11")
]
#=> [#<struct Dividend value=nil, dade="Jan 1">,
# #<struct Dividend value=10, date="Mar 22">,
# #<struct Dividend value=13, date="Apr 21">,
# #<struct Dividend value=nil, date="Aug 7">,
# #<struct Dividend value=8, date="Oct 11">]
然后,例如,
inst = historical[3]
#=> #<struct Dividend value=nil, date="Aug 7">
inst.value
#=> nil
inst.date
#=> "Aug 7"
我们可以写
historical.filter_map do |inst|
[inst.value, inst.date] unless inst.value.nil?
end.transpose
#=> [[10, 13, 8], ["Mar 22", "Apr 21", "Oct 11"]]
注意
historical.filter_map do |inst|
[inst.value, inst.date] unless inst.value.nil?
end
#=> [[10, "Mar 22"], [13, "Apr 21"], [8, "Oct 11"]]
如果你有两个具有相应元素的数组,例如:
values = [1, nil, 3]
dates = [Date.new(2022, 5, 1), Date.new(2022, 5, 2), Date.new(2022, 5, 3)]
您可以使用 transpose
:
[dividend, date]
对的组合数组
values_with_dates = [values, dates].transpose
#=> [[1, #<Date: 2022-05-01>], [nil, #<Date: 2022-05-02>], [3, #<Date: 2022-05-03>]]
然后您可以通过 reject!
:
nil
的元素
values_with_dates.reject! { |value, date| value.nil? }
#=> [[1, #<Date: 2022-05-01>], [3, #<Date: 2022-05-03>]]
然后 transpose
再次将对分开:
values_with_dates.transpose
#=> [[1, 3], [#<Date: 2022-05-01>, #<Date: 2022-05-03>]]
可以使用 Ruby 的 multiple assignment.
将内部数组分配回单独的变量作为 one-liner:
values, dates = [values, dates].transpose.reject { |v, _| v.nil? }.transpose