Помогите с преобразованием массивов и хэшей - PullRequest
0 голосов
/ 11 апреля 2011

Я пытаюсь использовать 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 по дням, как каждый элемент в data.

У меня проблемы с нахождением "рубинового способа" сделать это элегантно, я не супер крут в манипулировании массивами и хэшами, как вы, вероятно, можете видеть, но могу помочь мне в достижении этой цели. путь ценится.


Во-вторых, я пытался выполнить это, используя group() в своем запросе, но это не очень помогает, мысли? Еще одна вещь, которую мне нужно решить, это заполнить даты «0», если для этого нет записей ... но я остановлюсь на этом, я думаю.

Ответы [ 3 ]

1 голос
/ 11 апреля 2011
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.

1 голос
/ 11 апреля 2011

Я бы использовал 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.Используйте правильную версию, или require "backports".

1 голос
/ 11 апреля 2011

Что-то вроде этого должно работать:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...