帮助转换数组和哈希

发布于 2024-10-31 05:22:48 字数 1334 浏览 0 评论 0原文

我正在尝试在我的网络应用程序中使用 Highcharts,但在让我的数组匹配 highcharts 所需的输出时遇到一些麻烦,本质上 hightcharts 需要像这样的 JS 输出:

series: [{
   name: 'person',
   data: [1562, 873, 1457]
}, {
   name: 'car',
   data: [7323, 324, 1233]
}, {
   name: 'SUV',
   data: [832, 6232, 4432]
}]

在这种情况下,数据数组中的每个项目新的一天开始了,我的问题是我的数据组织方式有点不同,尝试转换我的数据以匹配这一点一直是一件令人头痛的事情。基本上我的输出是这样的:

[
  {:date=>"Sun, 10 Apr 2011", :object_types=>[
    {:count=>4279, :class_name=>"person"}, 
    {:count=>8785, :class_name=>"car"}, 
    {:count=>2153, :class_name=>"SUV"}
  ]}, 
  {:date=>"Sat, 09 Apr 2011", :object_types=>[
    {:count=>12206, :class_name=>"person"}, 
    {:count=>29095, :class_name=>"car"}, 
    {:count=>7565, :class_name=>"SUV"}
  ]}, 
  {:date=>"Fri, 08 Apr 2011", :object_types=>[
    {:count=>4159, :class_name=>"person"}, 
    {:count=>8043, :class_name=>"car"}, 
    {:count=>1982, :class_name=>"SUV"}
  ]}
] 

所以看来我主要需要将项目首先按(在我的情况下) :class_name 分组,然后在其中 :count 按天作为数据中的每一项。

我很难找到优雅地执行此操作的“Ruby 方式”,正如您可能看到的那样,我在操作数组和哈希方面并不是非常出色,但是任何指导我以正确的方式完成此操作的帮助都会受到赞赏。


其次,我最初尝试在查询中使用 group() 来完成此操作,但这似乎没有多大帮助,您想吗?我必须解决的另一件事是,如果没有记录,则用“0”填充日期......但我想接下来我会解决这个问题。

I'm trying to use Highcharts in my web app, but I'm having some trouble getting my arrays to match the output that highcharts needs, essentially hightcharts needs output like this in it's JS:

series: [{
   name: 'person',
   data: [1562, 873, 1457]
}, {
   name: 'car',
   data: [7323, 324, 1233]
}, {
   name: 'SUV',
   data: [832, 6232, 4432]
}]

Where each item in the data array in this case is a new day, my problem is that my data is organized a bit differently, and trying to transform my data to match this has been a headache. basically my output is like so:

[
  {:date=>"Sun, 10 Apr 2011", :object_types=>[
    {:count=>4279, :class_name=>"person"}, 
    {:count=>8785, :class_name=>"car"}, 
    {:count=>2153, :class_name=>"SUV"}
  ]}, 
  {:date=>"Sat, 09 Apr 2011", :object_types=>[
    {:count=>12206, :class_name=>"person"}, 
    {:count=>29095, :class_name=>"car"}, 
    {:count=>7565, :class_name=>"SUV"}
  ]}, 
  {:date=>"Fri, 08 Apr 2011", :object_types=>[
    {:count=>4159, :class_name=>"person"}, 
    {:count=>8043, :class_name=>"car"}, 
    {:count=>1982, :class_name=>"SUV"}
  ]}
] 

So it seems that I need to primarily have the items first grouped by (in my case) :class_name, then within that the :count by day as each item in data.

I'm having trouble find the the "ruby way" to do this elegantly, I'm not super awesome at manipulating arrays and hashes as you can probably see, but any bit of help in guiding me towards accomplishing this the right way is appreciated.


Secondly, I tried to accomplish this using group() in my query originally but that doesnt seem to be helping much, thoughts? Another thing I'll have to solve is filling dates with "0" if there are no records for it... but I'll tackle that next I think.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疑心病 2024-11-07 05:22:48

我会使用 Enumerable#group_by,因为这是更难的部分;剩下的只是基本转换:

r = data.flat_map{|h| h[:object_types]}.
  group_by{|h| h[:class_name]}.
  map do |class_name, hashes|
    {:name => class_name, :data => hashes.map{|h| h[:count]}}
  end

注意group_by位于ActiveRecord或Ruby 1.8.7+中。 flat_map 是 Ruby 1.9.2 的新增功能。使用正确的版本,或需要“反向移植”

I would use Enumerable#group_by, because that's the harder part; the rest is just basic transformation:

r = data.flat_map{|h| h[:object_types]}.
  group_by{|h| h[:class_name]}.
  map do |class_name, hashes|
    {:name => class_name, :data => hashes.map{|h| h[:count]}}
  end

Note: group_by is in ActiveRecord or Ruby 1.8.7+. flat_map is new to Ruby 1.9.2. Use the right version, or require "backports".

喜爱皱眉﹌ 2024-11-07 05:22:48

像这样的事情应该可行:

def convert_data(input) 
  hash = {} 
  input.each do |o| 
    o[:object_types].each do |ot| 
      if hash[ot[:class_name]] 
        hash[ot[:class_name]] << ot[:count] 
      else 
        hash[ot[:class_name]] = [ot[:count]] 
      end 
    end 
  end 
  hash.map {|k,v| {'name' => k, 'data' => v}}
end

您可以使用输入数据调用此函数,并且您将获得一个符合您期望的 Highcharts 库格式的对象。

Something like this should work:

def convert_data(input) 
  hash = {} 
  input.each do |o| 
    o[:object_types].each do |ot| 
      if hash[ot[:class_name]] 
        hash[ot[:class_name]] << ot[:count] 
      else 
        hash[ot[:class_name]] = [ot[:count]] 
      end 
    end 
  end 
  hash.map {|k,v| {'name' => k, 'data' => v}}
end

You can call this function with your input data and you've got an object which fits the format you expect for the Highcharts library.

墨落画卷 2024-11-07 05:22:48
aux = Hash.new(Array.new)
series = Array.new

# After this code the aux hash will look something like this: {:person => [4159, 1231, 255], :suv => [1231, 4123, 5411], :car => [321, 312, 541]}
raw_array.each do |date_hash|
  date_hash[:object_types].each do |inf|
    aux[inf[:class_name]] << inf[:count]
  end
end

aux.each { |k,v| series << {:name => k.to_s, :data => v} }

那么该系列数组就是您所需要的。像json一样渲染就可以了。

aux = Hash.new(Array.new)
series = Array.new

# After this code the aux hash will look something like this: {:person => [4159, 1231, 255], :suv => [1231, 4123, 5411], :car => [321, 312, 541]}
raw_array.each do |date_hash|
  date_hash[:object_types].each do |inf|
    aux[inf[:class_name]] << inf[:count]
  end
end

aux.each { |k,v| series << {:name => k.to_s, :data => v} }

Then that series array is what you need. Just render it like json.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文