What is that method called?

D

David Trasbo

I need the method that has the ability to turn a long string like this:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
pulvinar turpis a nisi. Cras id elit. Aliquam vitae pede nec lacus
elementum lacinia. Ut aliquam vehicula sem.

into a shorter string like this:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
pulvinar turpis...

My problem is that I can't remember what the method is called. I looked
through the whole Ruby String documentation
(http://ruby-doc.org/core/classes/String.html) but I couldn't find it.
Can anyone remember what it's called?
 
C

Clifford Heath

David said:
I need the method that has the ability to turn a long string... into a shorter string...
My problem is that I can't remember what the method is called. I looked
through the whole Ruby String documentation...

There's no such method in Ruby. You might be thinking of the
truncate method that's part of ActionView's TextHelper module.

Clifford Heath.
 
D

David Trasbo

Peter said:
I seriously doubt this is part of standard Ruby.

You're right, it's not a part of the Ruby standard library:

Clifford said:
There's no such method in Ruby. You might be thinking of the
truncate method that's part of ActionView's TextHelper module.

truncate is what it's called. I was actually searching for 'rails
StringHelper'... :)

Thanks for the replies!
 
J

Justin Collins

[Note: parts of this message were removed to make it a legal post.]

David said:
You're right, it's not a part of the Ruby standard library:



truncate is what it's called. I was actually searching for 'rails
StringHelper'... :)

Thanks for the replies!

Also:

a_long_string = "Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Pellentesque pulvinar turpis a nisi. Cras id elit. Aliquam vitae
pede nec lacus elementum lacinia. Ut aliquam ehicula sem."
limit = 86
a_long_string[0, limit] << "..." #=> "Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Pellentesque pulvinar turpis..."


-Justin
 
B

Boris Blaadh

perhaps this works?




string = <<END
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
pulvinar turpis a nisi. Cras id elit. Aliquam vitae pede nec lacus
elementum lacinia. Ut aliquam vehicula sem.
END

lead = 90

wordlist = string.split(' ')

shorttext = ''

for word in wordlist

break if(shorttext.length + word.length > lead)
shorttext = shorttext + word + " "

end

# get rid of the last space
shorttext.chop!

puts "#{shorttext}..."
 
B

Brian Adkins

Justin Collins said:
[Note: parts of this message were removed to make it a legal post.]

David said:
You're right, it's not a part of the Ruby standard library:



truncate is what it's called. I was actually searching for 'rails
StringHelper'... :)

Thanks for the replies!

Also:

a_long_string = "Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Pellentesque pulvinar turpis a nisi. Cras id elit. Aliquam vitae
pede nec lacus elementum lacinia. Ut aliquam ehicula sem."
limit = 86
a_long_string[0, limit] << "..." #=> "Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Pellentesque pulvinar turpis..."

In general, for input strings less than the limit, you wouldn't want "..."

class String
# Return an ellided string no longer than total_length
# "hello".ellide(5) -> "hello"
# "hello there".ellide(8) -> "hello..."
def ellide total_length
if self.length > total_length
raise 'total_length must be at least 3' if total_length < 3
return self[0, total_length - 3] + '...'
else
return self
end
end
end
 
B

Brian Adkins

Boris Blaadh said:
perhaps this works?

string = <<END
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
pulvinar turpis a nisi. Cras id elit. Aliquam vitae pede nec lacus
elementum lacinia. Ut aliquam vehicula sem.
END

lead = 90

wordlist = string.split(' ')

shorttext = ''

for word in wordlist

break if(shorttext.length + word.length > lead)
shorttext = shorttext + word + " "

end

# get rid of the last space
shorttext.chop!

puts "#{shorttext}..."

It is nicer to break at word boundaries in some contexts. But if it's
a single word (such as a long email address), then you'd still want to
show something more than "...". Maybe you can add a check for that.

e.g. for string = '(e-mail address removed)', lead = 15
 
B

Boris Blaadh

Brian said:
It is nicer to break at word boundaries in some contexts. But if it's
a single word (such as a long email address), then you'd still want to
show something more than "...". Maybe you can add a check for that.

e.g. for string = '(e-mail address removed)', lead = 15

Hehe, ok:

if shorttext.empty?
puts wordlist[0]
else
puts "#{shorttext}..."
end
 
B

Brian Adkins

Boris Blaadh said:
Brian said:
It is nicer to break at word boundaries in some contexts. But if it's
a single word (such as a long email address), then you'd still want to
show something more than "...". Maybe you can add a check for that.

e.g. for string = '(e-mail address removed)', lead = 15

Hehe, ok:

if shorttext.empty?
puts wordlist[0]
else
puts "#{shorttext}..."
end

That fixes the problem of showing only '...', but now 'puts
wordlist[0]' may display more than the limit.

Refining your idea a bit gave the following:

def elide_words total_length
return self unless self.length > total_length
raise 'total_length must be at least 3' if total_length < 3
words = self.split(' ')
result = ''
words.each do |word|
len = total_length - (result.empty? ? 3 : 4)
break if result.length + word.length > len
result << ' ' unless result.empty?
result << word
end
if result.empty?
return self.elide(total_length)
else
return result + '...'
end
end

But we really don't need to find *all* the space boundaries via
split(), so the following version is about 10 times faster:

def elide_words total_length
return self unless self.length > total_length
raise 'total_length must be at least 3' if total_length < 3
len = total_length - 3 # room for '...'

# Case 1: natural word break
return self[0, len] + '...' if self[len,1] == ' '

# Case 2: search backward for a char preceding a delimiter
delim_found = false
idx = len.downto(0) {|i|
if delim_found
break (i + 1) if self[i,1] != ' '
else
delim_found = true if self[i,1] == ' '
end
}

return self[0, idx] + '...'
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,196
Messages
2,571,036
Members
47,631
Latest member
kukuh

Latest Threads

Top