Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find next char boundary index in string after char

Tags:

string

char

rust

Given the string s, and the index i which is where the character starts:

let s = "abc 好 def";
let i = 4;

What's the best way to get the index after that character, so that I can slice the string and get abc 好? In code:

let end = find_end(s, i);
assert_eq!("abc 好", &s[0..end]);

(Note, + 1 doesn't work because that assumes that the character is only 1 byte long.)

I currently have the following:

fn find_end(s: &str, i: usize) -> usize {
    i + s[i..].chars().next().unwrap().len_utf8()
}

But I'm wondering if I'm missing something and there's a better way?

like image 939
robinst Avatar asked Apr 07 '17 12:04

robinst


1 Answers

You could use char_indices to get the next index rather than using len_utf8 on the character, though that has a special case for the last character.

I would use the handy str::is_char_boundary() method. Here's an implementation using that:

fn find_end(s: &str, i: usize) -> usize {
    assert!(i < s.len());
    let mut end = i+1;
    while !s.is_char_boundary(end) {
        end += 1;
    }
    end
}

Playground link

Normally I would make such a function return Option<usize> in case it's called with an index at the end of s, but for now I've just asserted.

In many cases, instead of explicitly calling find_end it may make sense to iterate using char_indices, which gives you each index along with the characters; though it's slightly annoying if you want to know the end of the current character.

like image 171
Chris Emerson Avatar answered Sep 20 '22 12:09

Chris Emerson