Problem overview
The function get_full_names_2 receives a Vec<String> called names. The vector lists people's names in pairs: a first name, then the matching last name, then the next person's first name, and so on. The function must return a new Vec<String> with one full name per pair, written as the first name, one space, and the last name.
For ["John", "Doe", "Andy", "Smith", "Mary", "Johnson"] the result is ["John Doe", "Andy Smith", "Mary Johnson"]. Six strings go in and three come out, because every two neighbouring strings merge into one.
Approach: visit the even indices
First names always sit at the even positions 0, 2, 4, and so on, and each last name sits right after its first name, at the next odd position. So the task is to look at the positions 0, 2, 4, ... and, at each one, combine the string there with the string after it.
A loop that visits every index and skips the odd ones would work, but Rust has a cleaner tool: take the range of all indices, 0..names.len(), and ask it to move two at a time with step_by(2). The loop variable then lands only on first names, and index + 1 is always the partner.
Step by step
- Create an empty vector named
answer. It must be declared withlet mut, because pushing into it changes it. You don't write its element type: the compiler sees that you later pushStringvalues and fills it in. - Loop over the even indices. The range
0..names.len()covers every valid index, andstep_by(2)keeps every second one. The range is wrapped in parentheses so the method call applies to the whole range. - Build the full name with the
format!macro. It works likeprintln!, but instead of printing it returns a newString. Each{}is replaced by the next argument, so"{} {}"puts a single space between the two parts. - Push the full name onto
answer. Pushing adds to the end, so the full names come out in the same order as the pairs went in. - Return
answerafter the loop, not inside it. Areturninside the loop would end the function after the first pair.
The solution in Rust
impl Solution {
fn get_full_names_2(names: Vec<String>) -> Vec<String> {
let mut answer = Vec::new();
for index in (0..names.len()).step_by(2) {
let name = format!("{} {}", names[index], names[index + 1]);
answer.push(name);
}
return answer;
}
}
Rust details worth knowing:
- The index type is
usize.names.len()returns ausize, so the range, and thereforeindex, is ausizetoo. That is the type Rust requires for indexing a vector, so no conversion is needed. format!borrows its arguments. Writingnames[index]inside the macro doesn't move the string out of the vector. The macro only reads it, sonamesstays intact, and the result is a brand-newStringthat owns its own text.- Type inference.
Vec::new()alone doesn't say what the vector holds. Becauseanswer.push(name)passes aStringand the function returnsVec<String>, the compiler concludes thatansweris aVec<String>. - Half-open ranges.
0..6contains 0 through 5. Withstep_by(2)it yields 0, 2 and 4. For a length of 7 it would yield 0, 2, 4 and 6. returnat the end. The finalreturn answer;is correct. Idiomatic Rust often writes justansweras the last expression, without a semicolon; both return the same value.
Edge cases and common mistakes
- Empty input. With an empty vector the range is empty, the loop never runs, and the function returns an empty vector.
- Exactly one pair.
["Ann", "Lee"]gives["Ann Lee"]. - An odd number of names. The task promises pairs, so this shouldn't happen. If it did, the last index would be even, and
names[index + 1]would read one position past the end. Indexing out of bounds panics, so["A", "B", "C"]would stop the program with an "index out of bounds" message. - Forgetting
mut. Withoutlet mut, the compiler rejectsanswer.push(name), because pushing changes the vector. - Stepping by 1. A plain
for index in 0..names.len()would also pair each last name with the next first name, producing strings like"Doe Andy", and the final index would read past the end and panic. - Missing space.
"{}{}"would glue the names together as"JohnDoe". - Returning inside the loop. Only the first full name would come back.
Testing
["John", "Doe", "Andy", "Smith", "Mary", "Johnson"]gives["John Doe", "Andy Smith", "Mary Johnson"].["Ann", "Lee"]gives["Ann Lee"].[]gives[].
