【问题标题】:How To Reject An Element From An Array?如何拒绝数组中的元素?
【发布时间】:2011-12-27 13:40:05
【问题描述】:

我正在将 Highcharts 合并到我的 Rails 3/Ruby 1.8.7 项目中,使用 Railscast 第 223 集作为起点。

我正在尝试绘制用户在过去 4 周内的体重图表。有些日子用户可能不会输入他们的体重,我希望图表跳过这些日期。

我尝试使用这个 Stackoverflow 问题的答案:

Highcharts - Rails array includes empty date entries

但我遇到了 OP 提到的同样问题,因为重量值被分配给没有条目的日期。简而言之,没有权重的日期仍然被分配给找到下一个权重值的数组。

这是我图表系列选项中的代码:

  series: [{
      name: "Daily Weight",
      pointInterval: <%= 1.day * 1000 %>,
      pointStart: <%= 4.weeks.ago.to_i * 1000 %>,
      data: <%= (4.weeks.ago.to_date..Date.today).map { |date| Weight.weight_on(date, current_user.id).to_f}.reject(&:zero?).inspect %>
    }]

这是来自权重模型的 weight_on 函数:

def self.weight_on(date, user_id)
  weight = Weight.find_by_entry_date_and_user_id(date, user_id)
  unless weight.nil?
    return weight.weight_entry
  end
end

看起来正在发生的事情是在构建日期/权重数组时,日期被保留,直到返回权重值。然后在迭代到下一个日期之前将日期和权重(与数组中的日期不对应)添加到数组中。

我如何也拒绝约会?如果没有找到该日期的重量值,我该如何跳过该日期,确保它不会被添加到数组中,然后继续下一个日期?

感谢您的帮助!

【问题讨论】:

  • 不完全是一个答案,而是一个建议:您应该创建一个日历表 [1] 并将您的数据留给它,而不是在您的应用程序中迭代日期并查询每天的数据库。 [1]sqlserver2000.databases.aspfaq.com/…

标签: javascript ruby-on-rails ruby ruby-on-rails-3 highcharts


【解决方案1】:

我会使用不规则的间隔来重构代码,而不是期望用户每天填写值。

生成日期时间(以毫秒为单位)和值对,即每个点的数组都有一个 x 和 y 值。

 new Highcharts.Chart({    
  chart: {
     renderTo: 'container',
     type: 'line'
  },

  xAxis: {
     type: 'datetime',
     maxZoom: 7 * 24 * 3600000, // one week

  },

  series: [

    {
  name: "Weight",
          data: [[1295954580000,3.9],[1297411200000,6.6],1298366040000,5.5],1318931520000,7.7],[1320143220000,2.2],[1320846960000,5.6],[1321356600000,2.1]]
    }
});

http://www.highcharts.com/demo/spline-irregular-time

【讨论】:

  • 是的,就是这样做的。我在查看 Highcharts 不规则间隔示例时发现了这一点。您对毫秒的使用使得动态生成数组变得更加简单。我只需要弄清楚如何正确使用 dateTimeLabelFormats,以便毫秒值显示为月、日、年。谢谢!
【解决方案2】:

您不应拒绝数组中的值,将它们保留为 nil(因此它们稍后在 JSON 中为 null)。另外,请使用to_json,而不是inspect

<%= date_intervals.map { |date| Weight.weight_on(date, current_user.id) }.to_json %>

更多重构:

def self.weight_on(date, user_id)
  Weight.find_by_entry_date_and_user_id(date, user_id).try(:weight_entry)
end

但无论如何,您应该能够在 User 对象(has_many :weights)上做到这一点:

user.weight_on(date)

【讨论】:

  • 感谢重构建议。我现在使用 User 对象来获取相关的体重数据。
【解决方案3】:

self.weight_on方法改为

def self.weight_on(date, user_id)
  weight = Weight.find_by_entry_date_and_user_id(date, user_id)
  if weight.nil?
    return 0.0
  else
    return weight.weight_entry
  end
end

这样做会使那些没有重量数据的日期变为return 0.0 (float),这将被.reject(&amp;:zero?) 拒绝。所以只会显示有体重数据的日期。

希望对您有所帮助。

【讨论】:

  • 我尝试了类似的方法,但问题是日期是使用 pointStart 选项生成的。生成的数组只是针对第一个日期填写,依此类推。正确的方法显示在下面@Henrik 的答案中。谢谢!
猜你喜欢
  • 2020-10-07
  • 2015-06-24
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
相关资源
最近更新 更多