One liner to limit Array of Words to less than N number of characters in Ruby?
What's the simplest way to limit an array of words such that the resulting array, when the words are joined, is less than 40 characters? Something that acts like this:
words = ["ruby", "rails", "jquery", "javascript", "html"]
words.join.length #=> 29
words.join(", ").length #=> 37
words = ["ruby", "rails", "jquery", "javascript", "html", "css", "api"]
words.join.length #=> 35
words.join(", ").length #=> 47
words.chunk(:max_chars => 40) #=> ["ruby", "rail开发者_JAVA技巧s", "jquery", "javascript", "html"]
Update
Got this so far:
def chop(array, separator = "", max = 40)
  result = []
  array.each do |word|
    break if (result.join(separator).length + word.length > max)
    result << word 
    result
  end
  result
end
Too bad there is a fencepost condition, otherwise this would be a much cleaner code with the take_while method
def chop(array, separator = "", max_size = 40)
  so_far = 0
  sep = separator.size
  array.take_while{|word| (so_far += word.size + sep) <= max_size + sep }
end
It checks it is less or equals than max_size + sep to compensate we are adding a separator to every word, even though the last one doesn't need it.
Here's a fun way, you need active support:
require 'active_support'
class Array
  def chunk(sep = "", max = 40)
    self.inject([]){|m,n| (m+[n]).sum(&:size)+sep.size*m.size-1<max ? m<<n : m}
  end
end
Now:
["ruby", "rails", "jquery", "javascript", "html", "css", "api"].chunk(", ") #=> ["ruby", "rails", "jquery", "javascript", "html"]
A slight variation on yours:
result = input.inject([]){|r,word|r<<word if r*separator+word.length < max}
def chop(arr, sep = "", max = 40)
  max += sep.size
  arr.take_while{|x| (max -= x.size + sep.size) >= 0 }
end
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论