# String#capitalize more complex

**URL:** <https://www.ruby-forum.com/t/string-capitalize-more-complex/164547>\
**Category:** Ruby\
**Created:** [April 2, 2009, 1:57pm UTC](https://www.ruby-forum.com/t/string-capitalize-more-complex/164547 "2009-04-02T13:57:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [April 2, 2009, 1:57pm UTC](https://www.ruby-forum.com/t/string-capitalize-more-complex/164547/1 "2009-04-02T13:57:01Z")

</div>

Hi, I receive headers (the protocol syntax allows them being lowcase,  
upcase or a mix). For example, the following header names are  
equivalent:

a) Record-Route  
b) record-route  
c) RECORD-ROUTE  
d) Record-ROUTE

I’m trying to do a method to convert all of them to:

Record-Route

Basically what I need is to capitalize all the header name parts after  
splitting it using “-” as separator. I can do it as follows:

* * *

## hname = “Record-ROUTE” hname.split("-").map {|w| w.capitalize }.join("-") } =\> “Record-Route”

Benchmark.realtime { hname.split("-").map {|w| w.capitalize }.join("-")  
}  
1.69277191162109e-05

Is there any option even faster? I think it would be faster if I  
operate directly in the original string instead of doing “split” and  
“join” (since these last methods create more strings so allocate  
memory for them and so). I would prefer to do the modification “in  
place”.

BTW, could I know how to convert “a” char into “A”? I expected  
something as in c:

‘a’ + 1 =\> ‘b’  
‘a’ + Â¿X? =\> ‘A’

but in Ruby#String I just find String#next which just increment the  
char in one unit (“a”.next =\> “b”).

Any suggestion? Thanks a lot.

Thanks a lot.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [April 2, 2009, 2:01pm UTC](https://www.ruby-forum.com/t/string-capitalize-more-complex/164547/2 "2009-04-02T14:01:07Z")

</div>

On Thu, Apr 2, 2009 at 1:55 PM, Iñaki Baz C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> BTW, could I know how to convert “a” char into “A”? I expected  
> Thanks a lot.
> 
> –  
> Iñaki Baz C.  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

Have a look at Net::HTTPHeader and it’s code as all of this is handled  
in there  
[http://www.ruby-doc.org/core/classes/Net/HTTPHeader.html](http://www.ruby-doc.org/core/classes/Net/HTTPHeader.html)

Andrew T.  
[http://ramblingsonrails.com](http://ramblingsonrails.com)  
[http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)

“I have never let my schooling interfere with my education” - Mark Twain

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [April 2, 2009, 4:14pm UTC](https://www.ruby-forum.com/t/string-capitalize-more-complex/164547/3 "2009-04-02T16:14:44Z")

</div>

2009/4/2 IÃ±aki Baz C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Â ‘a’ + Â¿X? =\> ‘A’  
> I’ve done it in two ways:

* * *

require “benchmark”

hname1 = “record-route”  
hname2 = “record-route”

rt1=0.0  
rt2=0.0

### Method 1

1.upto(10) do  
rt1 += Benchmark.realtime { hname1 = hname1.split(“-”).map {|w|  
w.capitalize }.join(“-”) }  
end  
puts “hname1 = #{hname1} (time = #{rt1/10})”

### Method 2

## 1.upto(10) do i=0 rt2 += Benchmark.realtime do hname2.capitalize!.each\_byte do |b| if b==45 && i\<hname2.bytesize-1 hname2[i+1] = [hname2[i+1].unpack(“\*c”)[0] - 32].pack(“\*c”) end i+=1 end end end puts “hname2 = #{hname2} (time = #{rt2/10})”

Results:

hname1 = Record-Route (time = 8.24928283691406e-06)  
hname2 = Record-Route (time = 1.05381011962891e-05)

This is: even if method 1 uses split and join (so it generates new  
strings and stores them in memory) it’s faster than method 2.  
Unfortunatelly method 2 also generates strings. I really wonder if  
there is a nicer way to do the same in a more fast way.

Thanks.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [April 2, 2009, 3:23pm UTC](https://www.ruby-forum.com/t/string-capitalize-more-complex/164547/4 "2009-04-02T15:23:47Z")

</div>

2009/4/2 Andrew T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Have a look at Net::HTTPHeader and it’s code as all of this is handled in there  
> [http://www.ruby-doc.org/core/classes/Net/HTTPHeader.html](http://www.ruby-doc.org/core/classes/Net/HTTPHeader.html)

Thanks. That approach doesn’t address the case I want but there are  
interesting ideas.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [April 2, 2009, 8:14pm UTC](https://www.ruby-forum.com/t/string-capitalize-more-complex/164547/5 "2009-04-02T20:14:01Z")

</div>

On Apr 2, 7:55 am, Iñaki Baz C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Benchmark.realtime { hname.split(“-”).map {|w| w.capitalize }.join(“-”) }
> 
> ‘a’ + 1 =\> ‘b’  
> ‘a’ + ¿X? =\> ‘A’
> 
> but in Ruby#String I just find String#next which just increment the  
> char in one unit (“a”.next =\> “b”).
> 
> Any suggestion? Thanks a lot.
> 
> Thanks a lot.

I would look at the camelcase implementations of Facets, English or  
ActiveSupport. They are pretty close to what you want. You may even be  
able to use one of them outright.

T.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [April 2, 2009, 8:30pm UTC](https://www.ruby-forum.com/t/string-capitalize-more-complex/164547/6 "2009-04-02T20:30:27Z")

</div>

El Jueves 02 Abril 2009, trans  
escribió:\> I would look at the camelcase implementations of Facets, English or

> ActiveSupport. They are pretty close to what you want. You may even be  
> able to use one of them outright.

Thanks, but finally I’ve decided to create a Ruby C extension for that.  
The  
code is very simple and fast:

* * *

/\*

- Capitalize each word of a header name. Examples:
- 
  - “record-route” =\> “Record-Route”

- 
  - “from” =\> “From”

- 
  - “VIA” =\> “Via”

- 

\*/

char \*string;  
int i;

string = XXXXXX

if ( string[0] \>= ‘a’ && string[0] \<= ‘z’ ) // ‘a’=97, ‘z’=122  
string[0] -= 32;

for (i=1; i\<strlen(string); i++) {  
if ( string[i-1] == ‘-’ && string[i] \>= ‘a’ && string[i] \<= ‘z’ )  
string[i] -= 32;  
else if ( string[i] \>= ‘A’ && string[i] \<= ‘Z’ )  
string[i] += 32;  
}
