How do I get the first character out of a string?

StringRust

String Problem Overview


I want to get the first character of a std::str. The method char_at() is currently unstable, as is String::slice_chars.

I have come up with the following, but it seems excessive to get a single character and not use the rest of the vector:

let text = "hello world!";
let char_vec: Vec<char> = text.chars().collect();
let ch = char_vec[0];

String Solutions


Solution 1 - String

UTF-8 does not define what "character" is so it depends on what you want. In this case, chars are Unicode scalar values, and so the first char of a &str is going to be between one and four bytes.

If you want just the first char, then don't collect into a Vec<char>, just use the iterator:

let text = "hello world!";
let ch = text.chars().next().unwrap();

Alternatively, you can use the iterator's nth method:

let ch = text.chars().nth(0).unwrap();

Bear in mind that elements preceding the index passed to nth will be consumed from the iterator.

Solution 2 - String

I wrote a function that returns the head of a &str and the rest:

fn car_cdr(s: &str) -> (&str, &str) {
    for i in 1..5 {
        let r = s.get(0..i);
        match r {
            Some(x) => return (x, &s[i..]),
            None => (),
        }
    }

    (&s[0..0], s)
}

Use it like this:

let (first_char, remainder) = car_cdr("test");
println!("first char: {}\nremainder: {}", first_char, remainder);

The output looks like:

first char: t
remainder: est

It works fine with chars that are more than 1 byte.

Solution 3 - String

It would be nice to have something similar to Haskell's head function and tail function for such cases.

I wrote this function to act like head and tail together (doesn't match exact implementation)

pub fn head_tail<T: Iterator, O: FromIterator<<T>::Item>>(iter: &mut T) -> (Option<<T>::Item>, O) {
    (iter.next(), iter.collect::<O>())
}

Usage:

// works with Vec<i32>
let mut val = vec![1, 2, 3].into_iter(); 
println!("{:?}", head_tail::<_, Vec<i32>>(&mut val));
// works with chars in two ways
let mut val = "thanks! bedroom builds YT".chars();
println!("{:?}", head_tail::<_, String>(&mut val));
// calling the function with Vec<char>
let mut val = "thanks! bedroom builds YT".chars();
println!("{:?}", head_tail::<_, Vec<char>>(&mut val));

> NOTE: The head_tail function doesn't panic! if the iterator is empty. If this matched Haskell's head/tail output, this would have thrown an exception if the iterator was empty. It might also be good to use iterable trait to be more compatible to other types.

Solution 4 - String

Get the first single character out of a string w/o using the rest of that string:

let text = "hello world!";
let ch = text.chars().take(1).last().unwrap();

Solution 5 - String

The accepted answer is a bit ugly!

let text = "hello world!";

let ch = &text[0..1]; // this returns "h"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionXAMPPRockyView Question on Stackoverflow
Solution 1 - StringSteve KlabnikView Answer on Stackoverflow
Solution 2 - StringSeanView Answer on Stackoverflow
Solution 3 - StringSukhinderpal MannView Answer on Stackoverflow
Solution 4 - StringKaplanView Answer on Stackoverflow
Solution 5 - StringFeFiFoFuView Answer on Stackoverflow