ruby - 在填补空白的同时合并两个数组
问题描述
我有一个day
对象。它有两个属性:where是一天的名称(“Monday”、“Tuesday” ....),而name
它是一个整数。magnitude
name
magnitude
我需要构建一个week
必须始终返回一个 7 s 的数组day
,一个用于一周中的每一天。
但是,有时,我得到的数组不到 7day
秒。IE
days = [<Day name: "Monday", magnitude: 4>,
<Day name: "Friday", magnitude: 3>,
<Day name: "Sunday", magnitude: 8>]
所以,为了建立一周,我想出了以下代码
default = Date::DAYNAMES.rotate(1).map{ |day| Day.new(name: day, magnitude: 0) }
default.map do |day|
days.detect do |other|
other.day == day.day
end || day
end
这行得通,但我觉得它很丑。我宁愿在两个数组之间进行联合。但是,我必须保留day
数组中 s 的顺序。Monday
必须始终是第一天而Sunday
最后一天。
关于如何改进上述代码的任何想法?
解决方案
Data
class Day
attr_accessor :name, :magnitude
def initialize(name, magnitude)
@name = name
@magnitude = magnitude
end
end
days = [["Monday", 4], ["Friday", 3], ["Sunday", 8]].map {|args|
Day.new(*args) }
#=> [#<Day:0x00005a1be9157548 @name="Monday", @magnitude=4>,
# #<Day:0x00005a1be91574d0 @name="Friday", @magnitude=3>,
# #<Day:0x00005a1be91574a8 @name="Sunday", @magnitude=8>]
Code
require 'date'
h = days.each_with_object({}) { |inst,h| h[inst.name] = inst }
#=> {"Monday"=>#<Day:0x00005a1be9157548 @name="Monday", @magnitude=4>,
# "Friday"=>#<Day:0x00005a1be91574d0 @name="Friday", @magnitude=3>,
# "Sunday"=>#<Day:0x00005a1be91574a8 @name="Sunday", @magnitude=8>}
h.default_proc = ->(h,d) { h[d] = Day.new(d,0) }
#=> #<Proc:0x00005a1be93ce858@(irb):26 (lambda)>
h.values_at(*Date::DAYNAMES.rotate(1))
#=> [#<Day:0x00005a1be9157548 @name="Monday", @magnitude=4>,
# #<Day:0x00005a1be93d8ec0 @name="Tuesday", @magnitude=0>,
# #<Day:0x00005a1be93d8e98 @name="Wednesday", @magnitude=0>,
# #<Day:0x00005a1be93d8e70 @name="Thursday", @magnitude=0>,
# #<Day:0x00005a1be91574d0 @name="Friday", @magnitude=3>,
# #<Day:0x00005a1be93d8e48 @name="Saturday", @magnitude=0>,
# #<Day:0x00005a1be91574a8 @name="Sunday", @magnitude=8>]
Explanation
See Hash#default_proc= and Hash#values_at. If h
does not have a key day
the default proc causes h
to return a new Day
object with @name
equal to the value of day
and @magnitude
equal to zero.
The first two expressions could be combined using (for example) Object#tap:
h = days.each_with_object({}) { |inst,h| h[inst.name] = inst }.
tap { |h| h.default_proc = ->(h,d) { h[d] = Day.new(d,0) }
推荐阅读
- swift - 我确定“textFiled.text!” 包含一个值。线程 1:致命错误:在展开可选值时意外发现 nil
- amazon-web-services - AWS 数据管道:将数据转储到 3 个 s3 节点
- cuda - fortran cudamalloc 和 cublassetmatrix 包装问题
- php - 使用 cURL 抓取重定向的 url
- arduino - 如何使用 ESP8266 Arduino 框架从 REST API 接收 JSON 响应
- java - 需要帮助了解使用 JFrame 类的 setRootPaneCheckingEnabled() 方法的原因
- apache-nifi - Apache NiFi EvaluateXQuery
- ios - 如何在 UITextField 中只允许没有任何空格和正好 8 个字符的数字和字母
- powershell - powershell RSA加密通过提供模数和指数
- typescript - 如何使用属性缩小类型