【问题标题】:How to convert a multi-key hash to single key hash in Ruby for Highcharts如何在 Ruby for Highcharts 中将多键散列转换为单键散列
【发布时间】:2016-09-17 08:34:32
【问题描述】:

我在 Ruby 中有这些数据,用于使用 Highcharts.js 创建条形图,需要 JSON 格式的数据:

data = {["January", "a"]=>54, ["January", "b"]=>13, ["January", "d"]=>2, ["January", "c"]=>1, 
        ["February", "a"]=>27, ["February", "b"]=>11, ["February", "c"]=>4, ["March", "a"]=>22, 
        ["March", "b"]=>11, ["March", "d"]=>2, ["March", "c"]=>2, ["April", "a"]=>32, 
        ["April", "b"]=>12, ["April", "d"]=>6, ["April", "c"]=>2, ["May", "a"]=>7, 
        ["May", "d"]=>3, ["June", "a"]=>5, ["July", "a"]=>25, 
        ["August", "a"]=>23, ["August", "d"]=>3, ["August", "c"]=>3, ["September", "a"]=>6}

数据存储在变量中,并非来自文件。

我想将其转换为 json 对象以将其发送到 Highcharts 进行制图。我需要以下格式的数据:

category = ["January","February","March","April","May","June","July","August","September"]

series: [{
            name: 'a',
            data: [54, 27, 22, 32, 7, 5, 25, 23, 6]
        }, {
            name: 'b',
            data: [13, 11, 11, 12, 6, 0, 0, 0, 6]
        }, {
            name: 'c',
            data: [1, 4, 0, 2, 0, 0, 0, 3, 6]
        },
            {
            name: 'd',
            data: [2, 0, 0, 6, 3, 0, 0, 3, 6]
        }]

数据丢失了几个月,有时不按字母顺序排列。

在 Ruby 中是否有一种简单的方法可以取消列出原始 Hash,然后从中提取信息,同时用 0 填充缺失值,并根据需要获取 JSON 输出?

附言:尝试转换 data.to_json 但 highcharts 不接受原始形式。有没有其他方法可以在 Highcharts 中使用这些数据创建条形图?

【问题讨论】:

    标签: ruby-on-rails json ruby ruby-on-rails-4 highcharts


    【解决方案1】:

    您可以尝试使用lazy_high_charts gem 在我们的控制器本身中渲染 HighCharts。

    因此可以轻松地为您的图表自定义数据。

    【讨论】:

      【解决方案2】:

      我不确定应该插入系列数据数组中的那些零的逻辑是什么,但这可能会让你快到那里:

      def transform(data)
        hash = { :category => [], :series => [] }
      
        data.keys().reduce(hash) { |accum, key|
          month = key[0]
          letter = key[1]
      
          # Push month
          accum[:category].push(month) if !accum[:category].include?(month)
      
          # Find existing item in series or create new one
          existing = accum[:series].select { |item| item[:name] == letter }
          item = existing.length > 0 ? existing[0] : {:name => letter, :data => []}
      
          # Push the number value in item's data
          item[:data].push(data[key])
      
          # Collect item if not already in series array
          accum[:series].push(item) if existing.length == 0
      
          accum
        }
      end
      
      result = transform(MY_DATA_HERE)
      result[:series].sort! {|a,b| a[:name] <=> b[:name] } # sort them!
      
      puts result
      

      输出:

      {
        :category=>["January", "February", "March", "April", "May", "June", "July", "August", "September"], 
        :series=>[
          {:name=>"a", :data=>[54, 27, 22, 32, 7, 5, 25, 23, 6]}, 
          {:name=>"b", :data=>[13, 11, 11, 12]}, 
          {:name=>"c", :data=>[1, 4, 2, 2, 3]}, 
          {:name=>"d", :data=>[2, 2, 6, 3, 3]}
        ]
      }
      

      【讨论】:

        【解决方案3】:
        catser = data.each_with_object(category: [], series: {}) do |(k, v), memo|
          memo[:category] << k.first
          (memo[:series][k.last] ||= []) << v
        end
        category, series = [
          catser[:category].uniq.sort,
          catser[:series].map { |k, v| { name: k, data: v } }
        ] 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-06-12
          • 2023-03-07
          • 2013-05-16
          • 2021-11-03
          • 2016-07-18
          • 1970-01-01
          • 1970-01-01
          • 2010-10-22
          相关资源
          最近更新 更多