How do you remove a sub-string according to index from a Rust String or &str type?

Viewed 3991

I have an &str type string from which I want to remove a sub-string. I have an algorithm to calculate the start and end positions of the part to be removed. How can I now remove the sub-string?

To illustrate this clearer, if I were using C++, I would do this:

#include<iostream>
#include<string>

    int main(){
        std::string foo = "Hello";
        int start = 2,stop = 4;
        std::cout<<foo;
        foo.erase(start, stop - start);
        std::cout<<std::endl<<foo<<std::endl;
    }

My code in Rust:

fn main(){
    let mut foo: &str = "hello";
    let start: i32 = 0;
    let stop: i32 = 4;
    //what goes here?
}
     
2 Answers

&str is an immutable slice, it somewhat similar to std::string_view, so you cannot modify it. Instead, you may use iterator and collect a new String:

let removed: String = foo
    .chars()
    .take(start)
    .chain(foo.chars().skip(stop))
    .collect();

the other way would be an in-place String modifying:

let mut foo: String = "hello".to_string();

// ...

foo.replace_range((start..stop), "");

Keep in mind, however, that the last example semantically different, because it operates on byte indicies, rather than char ones. Therefore it may panic at wrong usage (e.g. when start offset lay at the middle of multi-byte char).

Kitsu's solution w/o lambda

fn remove(start: usize, stop: usize, s: &str) -> String {
    let mut rslt = "".to_string();
    for (i, c) in s.chars().enumerate() {
        if start > i || stop < i + 1 {
            rslt.push(c);
        }
    }
    rslt
}

…as fast as replace_range but can handle unicode character

Playground

Related