Hacker News new | ask | show | jobs
by markov_twain 4886 days ago
so this is horribly non-idiomatic ruby, but it was fun

  p ->(*_) {
    _.reduce({}, :merge).tap { |_| return "<none>" if _.empty? }.keys.uniq.map(&:to_s).sort.join(", ")
  }.({c:3,d:4,b:2}, {f:5,e:4,a:1})
  
  p ->(*_) {
    _.reduce({}, :merge).tap { |_| return "<none>" if _.empty? }.keys.uniq.map(&:to_s).sort.join(", ")
  }.({}, {})
  
  # "a, b, c, d, e, f"
  # "<none>"
edit: a little bit better.

  func = ->(*_) {
    return "<none>" if _.all?(&:empty?)
    _.flat_map(&:keys).uniq.map(&:to_s).sort.join(", ")
  }
  
  func.({c:3,d:4,b:2}, {f:5,e:4,a:1})
  #=> "a, b, c, d, e, f"
  func.({}, {})
  #=> "<none>"
https://gist.github.com/66b45e765a2aa6a97143
2 comments

slightly more idiomatic, though perhaps not quite as clear as the clojure:

    def unique_keys(*hashes)
      result = {}
      hashes.each do |hash|
        result.merge! hash
      end
      return result.keys.map(&:to_s).sort.join(', ') unless result.empty?
      '<none>'
    end
https://gist.github.com/4695388
I think accumulating an initialized variable in an imperative #each loop is decidedly unidiomatic, just something we tend to do until we really embrace things like #map, #partition, #select, #reduce, etc. (And what a glorious day that is!)

I reckon what makes his first example somewhat unidiomatic is the arbitrary lambda and the use & inner return from the #taps block.

His updated example is just good ol tacit Ruby. But then again the amount of times I see an #each block with inner logic used instead of a simple point-free one-liner in Ruby really just proves your point.

well, I hate to beat a dead horse, but here's a one-liner (ruby):

  (map1.keys | map2.keys).map(&:to_s).sort.join(", ").instance_eval { empty? ? "<none>" : self }
My one-liner:

a = {"fred": 4, "wilma": 8} b = {"t-shirt": 6, "fred": 0}

print ", ".join(sorted(set(a).union(b))) or "<none>"