Solution Review for Chapter 8 Pig Latin

Firstly, I'd appreciate your support and indulgence on the code review: I have already searched this topic and note I'm not the first to pose this question, but the last was almost 2 years ago so I hope I'm not unduly breaking etiquette/imposing on rustaceans time.

The question is at the foot of this section

My goal is to use the language properly and this is where I got to. I'd love to hear some feedback if you'd be kind enough to take the time - particularly around adding/moving bits of strings.

muchas gracias

fn fn2() {
    let v = vec![
        "flippant",
        "motionless",
        "evasive",
        "resolute",
        "thumb",
        "canvas",
        "energetic",
        "dysfunctional",
        "concern",
        "nondescript",
        "bike",
        "feeble",
    ];

    let vowels = ['a', 'e', 'i', 'o', 'u'];

    let out: Vec<String> = v
        .iter()
        .map(|x| {
            if vowels.iter().any(|v| x.starts_with(*v)) {
                String::from(*x) + "hay"
            } else {
                ((String::from(*x)[1..]).to_string() + &((*x).chars().nth(0).unwrap().to_string()))
                    + "ay"
            }
        })
        .collect();
    println!("{:?}", v);
    println!("{:?}", out);
}

You could try checking out the format! macro :wink:

Also, using index 1.. can be wrong with special characters at the beginning of a word, so the task “Keep in mind the details about UTF-8 encoding!” would involve avoiding such an approach. On that note, also detecting accented vowels would be another challenge.

1 Like

Hey @steffahn thanks
So i thought that String[1..] indexes into the string scalars (i.e. respects unicode character boundaries). But your response suggests that's not the case? [1..] indexes into the bytes in the str?
thanks for the clarification

Yes, it indexes into the bytes in the str. (It's O(n)[1] to determine where the nth scalar boundary is.) Indexing and other non-Result-or-Option-returning index-based operations like split_at will panic if you pass in something that isn't a valid boundary.

More discussion here.


  1. "takes too long" ↩︎

2 Likes

I am not sure if I "cheated" or if I did it the "correct" way.
I used what I learned in the guessing game chapter. don't write a random function, use a crate.
I used the pig_latin crate and called it "done"

To be fair, it’s way harder to write a good (pseudo-)random generator and this is a situation where one would typically use a crate instead of rolling a custom implementation, especially if a cryptographically secure random generator is required ("don’t roll your own crypto"). That being said, implementing a linear congruential generator is still easy and reasonable enough depending on your needs (just steal good known parameters and don’t use it for cryptography). This could have been a good extra challenge for the guessing game chapter imo.

Ultimately it’s up to you to decide what is "cheating", but I wouldn’t say it’s "incorrect". Learning to find and use crates from the ecosystem like you did is a worthy exercise too. However, you didn’t exactly train to manipulate strings. Anyway, I think that setting your own challenges and following your curiosity is valuable as a learning process.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.