# Get ruby Hash#each to return a built hash

I'm golfing some code while waiting for a coworker, and I shortened a function to this:

def get_data(dir)

data = {}
$file_prefixes.each do |type, file_prefix| file = File.open("#{dir}/#{file_prefix}_#{newest[type]}.csv") file.readline data[type] = file.readlines end data end I feel like there must be some method to do away with that last line of just data. How can I get$file_prefixes.each to return data?

If it matters, $file_prefixes looks like this:$file_prefixes = {
:fixed_deal   => "PC2MMS_CMSS_DEALS_",
:fixed_offer  => "PC2MMS_CMSS_OFFERS_",
:mobile_deal  => "PC2MMS_NGBSS_DEALS_",
:mobile_offer => "PC2MMS_NGBSS_OFFERS_"
}

and newest is pretty much identical.

My target code might look something like this:

def get_data(dir)

data = {} # might even be able to get rid of this with clever use of Hash.new
data = $file_prefixes.each do |type, file_prefix| file = File.open("#{dir}/#{file_prefix}_#{newest[type]}.csv") file.readline ??? end end Disclaimer: I'm aware I could golf more by using single letter names, but I'm just trying to get it succinct and still readable ## 2 Answers Some notes: • Avoid the pattern init + each + update. Use map or other functional methods. • In Ruby >= 2.1.0 you have Array#to_h. Use Hash[...] in older Rubies. • Use File.join I'd write: def get_data(dir) newest = get_most_recent_file_numbers(dir)$file_prefixes.map do |type, file_prefix|
path = File.join(dir, file_prefix + "_" + newest[type] + ".csv")
end.to_h
end
• Hmmm... I need to discard the first line of the file, and I don't see a way to sneak that single readline in here without disrupting your logic. Perhaps I can just set the start for readlines at the first line someway? – Devon Parsons Oct 3 '14 at 18:24
• Aha! I can just change that last line to [type, File.readlines(path)[1,-1]]. Perfect! – Devon Parsons Oct 3 '14 at 18:27

tokland's answer is fine, but I thought I'd chime in and suggest using Enumerable#each_with_object instead of converting your data into an array and back.

def get_data(dir)