0

In python you can get the last 5 characters of a string like this:

s[-5:]

How do you do the same concisely in Rust? The best I could figure out was extremely verbose:

s.chars().rev().take(5).collect::<Vec<_>>().into_iter().rev().collect()
anothermh
  • 9,815
  • 3
  • 33
  • 52
Test
  • 962
  • 9
  • 26
  • [You should not *force* a tag into your title.](https://stackoverflow.com/help/tagging) Because the tags appear below the question and tags are indexed by search engines along with the content of your question, you can trust that other people will be able to find your question based on tags they follow or search for. – anothermh May 09 '23 at 17:06

1 Answers1

4

Using char_indices

let s = "Hello, World!";
let last_five = {
    let split_pos = s.char_indices().nth_back(4).unwrap().0;
    &s[split_pos..]
};
assert_eq!("orld!", last_five);

If you need to do this operations very often, consider to use UTF-32 encoding. To convert string to UTF-32, you need to do this: let utf_32: Vec<char> = s.chars().collect(). In such case you can do &utf_32[utf_32.len()-5..].

  • 1
    `nth_back(4)` is a tad shorter than `.rev().nth(4)`. Also, I'd say if you were going to do this often, you should just precompute the character indices of the string (`s.char_indices().map(|(idx, _)| idx).collect::>()`) rather than deal with vectors of `char`. – BallpointBen May 09 '23 at 17:49
  • 1
    @BallpointBen If you do that, you would use `8*num_chars` bytes for indices only and also would use from `1*num_chars` to `4*num_chars` bytes for string. My variant allows to use just `4*num_chars` bytes for all data (we don't really need original string anymore). So we get from 2 to 3 times less memory usage with UTF-32. – Angelicos Phosphoros May 09 '23 at 20:24
  • That's a good point! – BallpointBen May 10 '23 at 15:41