2
\$\begingroup\$

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

def get_data(dir)
  newest = get_most_recent_file_numbers(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)
  newest = get_most_recent_file_numbers(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

\$\endgroup\$
2
\$\begingroup\$

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")
    [type, File.readlines(path)]
  end.to_h
end
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 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? \$\endgroup\$ – Devon Parsons Oct 3 '14 at 18:24
  • \$\begingroup\$ Aha! I can just change that last line to [type, File.readlines(path)[1,-1]]. Perfect! \$\endgroup\$ – Devon Parsons Oct 3 '14 at 18:27
1
\$\begingroup\$

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)
  newest = get_most_recent_file_numbers(dir)

  $file_prefixes.each_with_object({}) do |mapping, hash|
    file = File.read("#{dir}/#{mapping.first}_#{newest[mapping.last]}
  end
end

In this example, I'm just using each_with_object to construct a new hash and populate it with values. You can also get rid of the need to call file = File.open ... file.readlines by just using File.read to get the same output.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.