Discussion:
[rust-dev] String capitalization
Oldřich Vetešník
2014-09-12 11:35:35 UTC
Permalink
Hello,

this is probably going to sound silly, but can this be written better?
I?d like to turn ?hello-there? into ?Hello There?.
I was thinking about something along the lines of split -> map -> capitalize -> join but the capitalization seems kind of awful to me.


use std::char;

fn name_from_file(file: String) -> String {
let mut words: Vec<&str> = file.as_slice().split('-').collect();
let mut cap_words = Vec::new();

for word in words.mut_iter() {
let first = char::to_uppercase(word.char_at(0)).to_string();
let rest = word.slice_chars(1, word.len());

let cap_word = first.append(rest);
cap_words.push(cap_word);
}

cap_words.connect(" ")
}

fn main() {
let hypenated_string = "hello-there".to_string();
let capitalized_string = name_from_file(hypenated_string);
println!("{}", capitalized_string);
}



Thanks,
Ollie
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140912/05ba8c5b/attachment.html>
Vladimir Matveev
2014-09-12 12:29:41 UTC
Permalink
Hi, Ollie,

This variant is terser, but it could be even more readable if there were some kind of connect() for iterators. It surprised me that there is no such thing in Rust iterators. It would be possible to use some kind of interleave() for iterators for the same purpose, but there is no such thing as well. Hence I had to use fold() and then pop_char() which is rather nasty as it breaks method chain.

On the other hand, this variant performs less allocations than your original version because the resulting string is allocated in advance.

use std::char;

fn name_from_file(file: String) -> String {
let mut r = file.as_slice().split('-')
.map(|w| char::to_uppercase(w.char_at(0)).to_string().append(w.slice_chars(1, w.len())))
.fold(
String::with_capacity(file.len()+1),
|r, w| r.append(w.as_slice()).append(" ")
);
r.pop_char();
r
}

fn main() {
let hypenated_string = "hello-there".to_string();
let capitalized_string = name_from_file(hypenated_string);
println!("{}", capitalized_string);
}

See it in action here: http://is.gd/UKKB96

BTW, I suggest you to use Stackoverflow [1] (preferred) or Reddit [2] to ask questions like this. The active community there is much larger than here, so you can get an answer quicker.

[1]: http://stackoverflow.com/questions/tagged/rust
[2]: http://www.reddit.com/r/rust/


On 12 ????. 2014 ?., at 15:35, Old?ich Vete?n?k <oldrich.vetesnik at gmail.com> wrote:

> Hello,
>
> this is probably going to sound silly, but can this be written better?
> I?d like to turn ?hello-there? into ?Hello There?.
> I was thinking about something along the lines of split -> map -> capitalize -> join but the capitalization seems kind of awful to me.
>
> use std::char;
>
> fn name_from_file(file: String) -> String {
> let mut words: Vec<&str> = file.as_slice().split('-').collect();
> let mut cap_words = Vec::new();
>
> for word in words.mut_iter() {
> let first = char::to_uppercase(word.char_at(0)).to_string();
> let rest = word.slice_chars(1, word.len());
>
> let cap_word = first.append(rest);
> cap_words.push(cap_word);
> }
>
> cap_words.connect(" ")
> }
>
> fn main() {
> let hypenated_string = "hello-there".to_string();
> let capitalized_string = name_from_file(hypenated_string);
> println!("{}", capitalized_string);
> }
>
>
> Thanks,
> Ollie
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
Ahmed Charles
2014-09-12 13:26:17 UTC
Permalink
> From: dpx.infinity at gmail.com
> Date: Fri, 12 Sep 2014 16:29:41 +0400
> To: oldrich.vetesnik at gmail.com
> CC: rust-dev at mozilla.org
> Subject: Re: [rust-dev] String capitalization
>
> Hi, Ollie,
>
> This variant is terser, but it could be even more readable if there were some kind of connect() for iterators. It surprised me that there is no such thing in Rust iterators. It would be possible to use some kind of interleave() for iterators for the same purpose, but there is no such thing as well. Hence I had to use fold() and then pop_char() which is rather nasty as it breaks method chain.
>
> On the other hand, this variant performs less allocations than your original version because the resulting string is allocated in advance.

This is what I tried to do as well. I think you can just check if r is empty and only append a space to it if it's not before appending w.

Note, I don't think either one is very readable.

> use std::char;
>
> fn name_from_file(file: String) -> String {
> let mut r = file.as_slice().split('-')
> .map(|w| char::to_uppercase(w.char_at(0)).to_string().append(w.slice_chars(1, w.len())))
> .fold(
> String::with_capacity(file.len()+1),
> |r, w| r.append(w.as_slice()).append(" ")
> );
> r.pop_char();
> r
> }
>
> fn main() {
> let hypenated_string = "hello-there".to_string();
> let capitalized_string = name_from_file(hypenated_string);
> println!("{}", capitalized_string);
> }
>
> See it in action here: http://is.gd/UKKB96
>
> BTW, I suggest you to use Stackoverflow [1] (preferred) or Reddit [2] to ask questions like this. The active community there is much larger than here, so you can get an answer quicker.
>
> [1]: http://stackoverflow.com/questions/tagged/rust
> [2]: http://www.reddit.com/r/rust/
>
>
> On 12 ????. 2014 ?., at 15:35, Old?ich Vete?n?k <oldrich.vetesnik at gmail.com> wrote:
>
> > Hello,
> >
> > this is probably going to sound silly, but can this be written better?
> > I?d like to turn ?hello-there? into ?Hello There?.
> > I was thinking about something along the lines of split -> map -> capitalize -> join but the capitalization seems kind of awful to me.
> >
> > use std::char;
> >
> > fn name_from_file(file: String) -> String {
> > let mut words: Vec<&str> = file.as_slice().split('-').collect();
> > let mut cap_words = Vec::new();
> >
> > for word in words.mut_iter() {
> > let first = char::to_uppercase(word.char_at(0)).to_string();
> > let rest = word.slice_chars(1, word.len());
> >
> > let cap_word = first.append(rest);
> > cap_words.push(cap_word);
> > }
> >
> > cap_words.connect(" ")
> > }
> >
> > fn main() {
> > let hypenated_string = "hello-there".to_string();
> > let capitalized_string = name_from_file(hypenated_string);
> > println!("{}", capitalized_string);
> > }
> >
> >
> > Thanks,
> > Ollie
> > _______________________________________________
> > Rust-dev mailing list
> > Rust-dev at mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140912/ace35ca6/attachment.html>
Oldřich Vetešník
2014-09-12 18:42:20 UTC
Permalink
Hehe, pretty ugly too :-), but thanks.

12. 9. 2014 v 14:29, Vladimir Matveev <dpx.infinity at gmail.com>:

> Hi, Ollie,
>
> This variant is terser, but it could be even more readable if there were some kind of connect() for iterators. It surprised me that there is no such thing in Rust iterators. It would be possible to use some kind of interleave() for iterators for the same purpose, but there is no such thing as well. Hence I had to use fold() and then pop_char() which is rather nasty as it breaks method chain.
>
> On the other hand, this variant performs less allocations than your original version because the resulting string is allocated in advance.
>
> use std::char;
>
> fn name_from_file(file: String) -> String {
> let mut r = file.as_slice().split('-')
> .map(|w| char::to_uppercase(w.char_at(0)).to_string().append(w.slice_chars(1, w.len())))
> .fold(
> String::with_capacity(file.len()+1),
> |r, w| r.append(w.as_slice()).append(" ")
> );
> r.pop_char();
> r
> }
>
> fn main() {
> let hypenated_string = "hello-there".to_string();
> let capitalized_string = name_from_file(hypenated_string);
> println!("{}", capitalized_string);
> }
>
> See it in action here: http://is.gd/UKKB96
>
> BTW, I suggest you to use Stackoverflow [1] (preferred) or Reddit [2] to ask questions like this. The active community there is much larger than here, so you can get an answer quicker.
>
> [1]: http://stackoverflow.com/questions/tagged/rust
> [2]: http://www.reddit.com/r/rust/
>
>
>> On 12 ????. 2014 ?., at 15:35, Old?ich Vete?n?k <oldrich.vetesnik at gmail.com> wrote:
>>
>> Hello,
>>
>> this is probably going to sound silly, but can this be written better?
>> I?d like to turn ?hello-there? into ?Hello There?.
>> I was thinking about something along the lines of split -> map -> capitalize -> join but the capitalization seems kind of awful to me.
>>
>> use std::char;
>>
>> fn name_from_file(file: String) -> String {
>> let mut words: Vec<&str> = file.as_slice().split('-').collect();
>> let mut cap_words = Vec::new();
>>
>> for word in words.mut_iter() {
>> let first = char::to_uppercase(word.char_at(0)).to_string();
>> let rest = word.slice_chars(1, word.len());
>>
>> let cap_word = first.append(rest);
>> cap_words.push(cap_word);
>> }
>>
>> cap_words.connect(" ")
>> }
>>
>> fn main() {
>> let hypenated_string = "hello-there".to_string();
>> let capitalized_string = name_from_file(hypenated_string);
>> println!("{}", capitalized_string);
>> }
>>
>>
>> Thanks,
>> Ollie
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev at mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>
Loading...