【问题标题】:How to create a new JSON object in every loop iteration如何在每次循环迭代中创建一个新的 JSON 对象
【发布时间】:2019-07-18 21:24:52
【问题描述】:

我正在开发一项功能,根据我的日常工作时间以及我的合同的开始和结束日期在日历中显示我的工作时间。问题是当我在同一天有 2 个或更多班次时。假设朱利安从 2019 年 7 月 17 日到 2019 年 7 月 31 日每周一从 03:00 到 04:00 和同一天从 5:00 到 6:00 换班。这意味着我的日历应该显示这 2 次轮班在 7 月 22 日和 7 月 29 日。我已经编写了逻辑来让我得到正确的日期。截至目前,我的 JSON 响应看起来像这样

{"user":"Julian","start":"2019-07-22","day":"Monday","start_time":["03:00","05:00"], "end_time":["04:00","06:00"]},{"user_":"Julian","start":"2019-07-29","day":"Monday","start_time ":["03:00","05:00"],"end_time":["04:00","06:00"]}

这是由我的 JSON 构建器文件中的以下代码生成的


        json.array! event.each do |inevent|

              json.id hr_schedule.id
              json.user_id hr_schedule.user_id

              json.start inevent.strftime('%Y-%m-%d') 
              day_of_week = inevent.strftime('%A') 
              json.day day_of_week
              if day_of_week == "Monday"
                  json.start_time hr_schedule.monday_st
                  json.end_time hr_schedule.monday_end  
              elsif day_of_week == "Tuesday"
                  json.start_time hr_schedule.tuesday_st
                  json.end_time hr_schedule.tuesday_end               
              elsif day_of_week == "Wednesday"
                  json.start_time hr_schedule.wednesday_st
                  json.end_time hr_schedule.wednesday_end   
              elsif day_of_week == "Thursday"

                  json.start_time hr_schedule.thursday_st
                  json.end_time hr_schedule.thursday_end    
              elsif day_of_week == "Friday"

                  json.start_time hr_schedule.friday_st
                  json.end_time hr_schedule.friday_end  

              elsif day_of_week == "Saturday"
                  json.start_time hr_schedule.saturday_st
                  json.end_time hr_schedule.saturday_end    
              elsif day_of_week == "Sunday" 
                  json.start_time hr_schedule.sunday_st
                  json.end_time hr_schedule.sunday_end  
              end



     end    

我想要实现的是能够将我的所有事件作为一个唯一的 JSON 对象,如下所示

{"user":"Julian","start":"2019-07-22","day":"Monday","start_time":"03:00","end_time":"04:00 "},{"user":"Julian","start":"2019-07-22","day":"Monday","start_time":"05:00","end_time":"06:00 "}, {"user":"Julian","start":"2019-07-29","day":"Monday","start_time":"03:00","end_time":"04:00"}, {"user":"Julian","start":"2019-07-29","day":"Monday","start_time":"05:00","end_time":"06:00"}

【问题讨论】:

  • @SergioTulentsev 这是一个错字,我更新了描述,它应该是从 03:00 到 04:00 以及同一天从 5:00 到 6:00 的另一个转变跨度>
  • json 是什么类?我不熟悉array! 方法。
  • @muistooshort:我认为在这种情况下,do/end 块将绑定到json.array!
  • 尽量不要使用英文单词作为你的逻辑的关键或驱动程序。数字或明确的机器可读代码几乎总是更好。如果某人将语言设置为英语以外的任何语言,这将无法在某人的计算机上运行,​​并且并非每个开发人员都会将英语设置为默认设置。
  • 你设置了json.user_id hr_schedule.user_id,但你得到了"user":"Julian""user_":"Julian"(注意下划线)。 useruser_ 是如何设置的? id 在哪里?你确定这是生成 JSON 的代码吗?

标签: ruby-on-rails json ruby ruby-on-rails-5


【解决方案1】:

我不确定json 是什么类,也不确定array! 在做什么。但是做你想做的事情的基本方法是使用map 将你的事件变成一个哈希数组。然后使用to_json将数组转换成JSON。

calendar = event.map do |inevent|
  json = {}

  json[:id] = hr_schedule.id
  json[:user] = hr_schedule.user_id

  json[:start] = inevent.strftime('%Y-%m-%d') 
  json[:day] = inevent.strftime('%A')

  case inevent.wday
  when 0
    json[:start_time] = hr_schedule.sunday_st
    json[:end_time] = hr_schedule.sunday_end  
  when 1
    json[:start_time] = hr_schedule.monday_st
    json[:end_time] = hr_schedule.monday_end  
  when 2
    json[:start_time] = hr_schedule.tuesday_st
    json[:end_time] = hr_schedule.tuesday_end               
  when 3
    json[:start_time] = hr_schedule.wednesday_st
    json[:end_time] = hr_schedule.wednesday_end   
  when 4
    json[:start_time] = hr_schedule.thursday_st
    json[:end_time] = hr_schedule.thursday_end    
  when 5
    json[:start_time] = hr_schedule.friday_st
    json[:end_time] = hr_schedule.friday_end  
  when 6
    json[:start_time] = hr_schedule.saturday_st
    json[:end_time] = hr_schedule.saturday_end    
  end

  json
end

puts calendar.to_json

我使用case/whenTime#wday 对其进行了一些简化。如果应用程序的语言发生变化,strftime(%A) 可能会发生变化,并且星期几的数字更难打错。


附带说明,此事件结构仅限于在午夜之前结束的事件。考虑改为使用完整的 ISO8061 日期时间作为开始和结束时间。一般来说,使用完整的日期时间比使用单独的日期和时间更容易。活动日期可以从start推断出来。

{"user":"Julian","start":"2019-07-22T03:00","end":"2019-07-22T04:00"}

或者,如果事件是相对的,例如每周一发生,请考虑开始和duration。并使用ISO weekday number 代替字符串,减少接收者的解析。

{"user":"Julian","day":1,"start":"03:00","duration":"P1H"}

【讨论】:

  • “我不确定 json 是什么类” - 它是 jbuilder DSL
  • 在定义 labels = { start: 'start_time', end: 'end_time' }appropriate_variable_name_that_does_not_come_to_mind = { start: [hr_schedule.sunday_st, hr_schedule.monday_st,..], end: hr_sunday_end, hr_monday_end,...] } 之后考虑 calendar = event.flat_map do |inevent|; [:start, :end].map do |when|; json = {};...
  • @CarySwoveland 你真的很喜欢你的数据映射。 :) 这种方法意味着您在循环的每次迭代中调用每个 X_stX_end 方法,这是浪费时间。相反,您将存储方法[:sunday_st, :monday_st, ...] 并使用send。这给这个答案带来了太多的复杂性。在这种情况下,根本问题是hr_schedule 的结构。与其将每一天的开始/结束时间存储在一个对象中,不如将其存储在一周中的每一天的一行中,其中包含星期几、开始时间和持续时间。然后schedule_for_day = hr_schedule.for_day(dow).
  • 如果您有一个将数字转换为天数的查找表,然后hr_schedule.send("#{day}_st") 等等,可以进一步简化此操作。
  • 那些方法(X_stX_end)没有参数,所以它们只被调用一次,当哈希 approp... 被构造时。因为它用一周中的wday 的循环替换了 case 语句,所以我认为它降低了复杂性并增加了剪切和粘贴然后忘记编辑错误的机会。
猜你喜欢
  • 1970-01-01
  • 2020-08-24
  • 1970-01-01
  • 2015-06-29
  • 1970-01-01
  • 2020-08-31
  • 2019-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多