LINUX.ORG.RU

краткий и эффективный &str join

 ,


0

5

нагуглил только такое:

fn reverse_words(s: &str) -> String {
  s.split_whitespace().rev().collect::<Vec<&str>>().join(" ")
}

но тут лишний вектор создается в куче. мой вариант, без лишней аллокации:

fn reverse_words(str: &str) -> String {
    let mut iter = str.split_whitespace().rev();
    if let Some(x) = iter.next() {
        let mut result = String::with_capacity(str.len());
        result += x;
        for x in iter {
            result += " ";
            result += x;
        }
        result
    } else {
        String::new()
    }
}

как сделать кратко и эффективно? заодно если расскажете, как можно сократить лапшу if let с итератором, будет вообще прекрасно

★★★★★

Последнее исправление: MyTrooName (всего исправлений: 3)

Ответ на: комментарий от Deleted

fold-у нужно передать init-аргумент; все равно такая же лапша будет, только со split_first

покажи свой вариант; желательно^Wсамо собой, чтобы строчки соединялись в одном буфере

MyTrooName ★★★★★
() автор топика
Последнее исправление: MyTrooName (всего исправлений: 1)
fn reverse_words(s: &str) -> String {
    let mut res = s.split_whitespace().rev().fold(
        String::with_capacity(s.len() + 1),
        |r, x| r + x + " ",
    );
    res.pop();
    res
}

https://is.gd/QRqo8n

pftBest ★★★★
()

Если нужен произвольный сепаратор, то делаем так как в реализации join, используем флаг.

fn reverse_words(src: &str, sep: &str) -> String {
    let mut res = String::with_capacity(src.len());
    let mut first = true;
    for it in src.split_whitespace().rev() {
        if first {
            first = false;
        } else {
            res.push_str(sep);
        }
        res.push_str(it);
    }
    res
}

https://is.gd/oV7X8d

pftBest ★★★★
()

Ты забыл пробульонстек? Работай со строками как с указателями на const, иначе никакой памяти не хватит

anonymous
()
Ответ на: комментарий от dzidzitop

split_whitespace() возвращает DoubleEndedIterator, это такой итератор у которого кроме функции next() которая идет вперед по строке, есть еще функция next_back() которая идет от конца строки к началу.

А rev() просто меняет местами функции next() и next_back().

pftBest ★★★★
()
Ответ на: комментарий от pftBest

почти так же длинно, но визуально чуть покрасивей, пожалуй

MyTrooName ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.