Fill string with repeated character

I'm in the process of learning Rust and came across this minor thing which seems more complicated than it ought to be. I want to create a string which contains a single character repeated N times.

The best I've come up with is this:
(0..n).map({ |_| "X" }).collect::<Vec<_>>().concat()

This is a bit verbose, and it has to allocate a temporary vector which is sub-optimal.

Are there more concise, idiomatic, or efficient ways to do this?

3 Likes

At the very least, you can simplify that by collecting directly into a String:

(0..10).map(|_| "X").collect::<String>();

Another way you could do it, possibly slightly more verbose but a little more clear, is to use repeat instead of a range and map:

std::iter::repeat("X").take(10).collect::<String>()
14 Likes

You can also do this:

String::from_utf8(vec![b'X'; 10]);

This does, unfortunately, take O(n) time because it validates that the string is valid utf8.

2 Likes

Any method of doing this will take at leas O(n) time, since you need to make n copies of the character.

1 Like

Sort of. It will actually take O(n) time because Vecs are constructed at runtime. ['X'; 10] is a constant (and free).

1 Like

If by "free" you mean "you paid that O(n) cost when loading the code from disk".

If it will happen once for a small vector that you might put in a constant, than the running time doesn't really matter. The running time only really matters if n is quite large, in which case, you would probably rather construct it at runtime only copying memory, rather than spending the time loading a huge array from disk, or if you will be doing this many times with different characters and lengths, in which you need a dynamic solution.

1 Like

Technically yes but with a very small coefficient...

I had a use for a repeated character today and found this question. I wanted to center a title like this:

-------- My title --------

and began searching for how to easily repeat the - character. The above solutions would have worked fine, but I ended up with a slightly simpler solution using format!. When specifying a width, you can specify a custom fill character:

let formatted_title = format!("{:-^1$}", title, n);

This centers the title within a line of n - characters. Use {:-<1$} for left alignment, and {:->1$} for right alignment. The - can be any character you like. See the format! documentation for more information.

I hope this can come in handy for others who need to fill some empty space with a repeated character!

23 Likes

str::repeat(n) -> String is a new unstable feature, it will come in handy soon when it stabilizes.

3 Likes

... and as of the newly released Rust 1.16, str::repeat is now a stable feature.

20 Likes