Efficient trimming of a String

怎甘沉沦 提交于 2019-12-01 03:53:53

a way to apply the trimming on a String without to allocate another one?

Yes, using truncate:

const TRAILER: &'static str = "UNI";

fn read_csv_rilev(s: &mut String) {
    while s.ends_with(TRAILER) {
        let len = s.len();
        let new_len = len.saturating_sub(TRAILER.len());
        s.truncate(new_len);
    }
}

fn main() {
    let mut code = "Hello WorldUNIUNIUNI".into();

    read_csv_rilev(&mut code);

    println!("{}", code);
}

Of course, you don't need to mess with the allocated string at all. You can use the same logic and make successive subslices of the string. This is basically how trim_right_matches works, but a bit less generic:

const TRAILER: &'static str = "UNI";

fn read_csv_rilev(mut s: &str) -> &str {
    while s.ends_with(TRAILER) {
        let len = s.len();
        let new_len = len.saturating_sub(TRAILER.len());
        s = &s[..new_len];
    }
    s
}

fn main() {
    let code = "Hello WorldUNIUNIUNI";

    let truncated = read_csv_rilev(code);

    println!("{}", truncated);
}

In general, I'd probably go with the second solution.

but probably an in-place action on a String is not a good idea.

The binding is mutable in mut s: &String, not the string itself. You would take s: &mut String if you wanted to mutate the string itself.

That said, I don't think there's anything in the standard library to do this.

Another solution is to use the owning_ref crate, which lets you return both a &str and its backing String at the same time:

extern crate owning_ref;
use owning_ref::StringRef;

fn read_csv_rilev(code: String) -> StringRef {
    StringRef::new(code).map(|s| s.trim_right_matches("UNI"))
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!