开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜