2011-03-28 3 views
2

Я использую этот массив хешей, чтобы сделать пакетную вставку в БД mongo. Каждый хэш был заполнен разбором текстового файла, поэтому форматирование полей находится в непредсказуемом формате. Это может выглядеть примерно так:Наиболее эффективный способ форматирования хэша данных?

{date => "March 5", time => "05:22:21", first_name = "John", middle_initial = "JJ", ...} 

И у меня будет ряд функций форматирования. Так что, может быть:

def format_date 
..convert if needed.. 
end 

def format_time 
... 
end 

Как я могу назвать функции форматирования для разных записей? Я мог видеть, что делает какой-то лямбда-вызов, где я перебираю хэш и вызываю функцию format_record_name, но не все записи будут иметь функции форматирования. Например, над записью first_name не потребуется. Есть идеи?

+0

I не совсем вопрос. Учитывая этот вклад, каков ожидаемый результат? – Matchu

+0

Извините, я обновил вопрос. Надеюсь, это яснее. –

+0

Вы должны указать примеры того, когда вы хотите изменить какие данные в какой форме. Вопрос не сформулирован достаточно. – sawa

ответ

1

Вот одна идея, очень похожая на то, что вы заявили. Вы можете просто иметь тождественную функцию для полей, которые вы не хотите форматировать

def pass(x) 
    x 
end 

method_hash = {:date=>method(:your_format_date)} 
method_hash.default = method(:pass) 

x = {:date => "March 5", :time => "05:22:21", :first_name => "John", :middle_initial => "JJ"} 
x.reduce({}) { |hsh,k| hsh[k[0]] = method_hash[k[0]].call(k[1]); hsh } 
2

Просто держите список ключей, которые вы хотите обработать. Можно даже связать его с функциями преобразования с Hash:

transformations = { 
    :date => lambda {|date| whatever}, 
    :time => lambda {|time| whatever} 
} 
transformations.default = lambda {|v| v} 

data.map do |hash| 
    Hash[ hash.map {|key, val| transformations[key][val] } ] 
end 
+0

Это выглядит как элегантное решение, но я не понимаю, что положить внутрь: date => lambda {| date | без разницы}. Я пробовал всевозможные способы доступа к значению в: date и не могу показаться. Но я также не могу просто вернуть поддельную ценность. –

0
class Formatters 
    def self.time(value) 
     "FORMATTED TIME" 
    end 

    def self.date(value) 
     "FORMATTED DATE" 
    end 

    def self.method_missing(name, arg) 
     arg 
    end 
end 

your_data = [{:date => "March 5", :time => "05:22:21", :first_name => "John", :middle_initial => "JJ"}, 
      {:date => "March 6", :time => "05:22:22", :first_name => "Peter", :middle_initial => "JJ"}, 
      {:date => "March 7", :time => "05:22:23", :first_name => "Paul", :middle_initial => "JJ"}] 

formatted_data = your_data.map do |item|  
    Hash[ *item.map { |k, v| [k, Formatters.send(k, v)] }.flatten ] 
end 
1

использование Сделать из Синглтон в Ruby (или Эйгеном) класса, а затем следующий один лайнер решает вашу проблему:

module Formatter 
    def format_date 
    Date.parse(self[:date]).strftime('%Y-%m-%d') 
    end 

    def format_time 
    self[:time].split(':')[0,2].join('-') 
    end 

    def format_first_name 
    self[:first_name].upcase 
    end 

    def format 
    {:date => format_date, :time => format_time, :first_name => format_first_name, :last_name => self[:last_name]} 
    end 
end 

records = [ 
    {:date => 'March 05', :time => '12:13:00', :first_name => 'Wes', :last_name => 'Bailey'}, 
    {:date => 'March 06', :time => '09:15:11', :first_name => 'Joe', :last_name => 'Buck'}, 
    {:date => 'March 07', :time => '18:35:48', :first_name => 'Troy', :last_name => 'Aikmen'}, 
] 

records.map {|h| h.extend(Formatter).format} 
=> [{:date=>"2011-03-05", :time=>"12-13", :first_name=>"WES", :last_name=>"Bailey"}, 
{:date=>"2011-03-06", :time=>"09-15", :first_name=>"JOE", :last_name=>"Buck"}, 
{:date=>"2011-03-07", :time=>"18-35", :first_name=>"TROY", :last_name=>"Aikmen"}] 
Смежные вопросы