1
\$\begingroup\$

This is the code I came up with for the Rust pig latin exercise.

I am looking for suggestions on how to make it more idiomatic.

I think working with iterators instead of chars and Strings would be a step in the right direction?

I was unable to figure out how to use .map to reach the same result. I would have liked to iterate over a SplitWhiteSpace and apply the manipulations to each slices in one pass instead of using a for loop.

Rust playground link

fn main() {
    let phrase = "Test sentence for pig latin f 🎈🎆🎇 नर र स्का स्कास्का 🧨".to_lowercase();
    let split = phrase.split_whitespace();
    let mut pigifyed: String = String::new();

    for word in split {
        let mut chars = word.chars();
        let firstchar = chars.next().unwrap();

        if chars.next() == None {
            pigifyed = format!("{} {}ay", pigifyed, firstchar)
        } else if is_vowel(&firstchar) {
            pigifyed = format!("{} {}-hay", pigifyed, word);
        } else {
            let end = &word[firstchar.len_utf8()..];
            pigifyed = format!("{} {}-{}ay", pigifyed, end, firstchar);
        }
    }
    println!("{}", pigifyed)
}

fn is_vowel(char: &char) -> bool {
    let vowels = ['a', 'e', 'i', 'o', 'u'];
    vowels.contains(char)
}

Output:

est-tay entence-say or-fay ig-pay atin-lay fay 🎆🎇-🎈ay र-नay रay ्का-सay ्कास्का-सay 🧨ay

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I can't see how you got stuck. You just do like you said: use map instead of Strings, then collect into a Vec, and finally join into one String.

Here is the code.

fn main() {
    let phrase = "Test sentence for pig latin f 🎈🎆🎇 नर र स्का स्कास्का 🧨".to_lowercase();
    let split = phrase.split_whitespace();

    let pigifyed = split.map(|word| {
        let mut chars = word.chars();
        let firstchar = chars.next().unwrap();

        if chars.next() == None {
            format!("{}ay", firstchar)
        } else if is_vowel(&firstchar) {
            format!("{}-hay", word)
        } else {
            let end = &word[firstchar.len_utf8()..];
            format!("{}-{}ay", end, firstchar)
        }
    }).collect::<Vec<String>>().join(" ");
    println!("{}", pigifyed)
}

fn is_vowel(char: &char) -> bool {
    let vowels = ['a', 'e', 'i', 'o', 'u'];
    vowels.contains(char)
}
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the demonstration on how to collect and join. I'll fiddle more with iterators to get comfortable with manipulating them. \$\endgroup\$ Dec 2, 2021 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.