signal-2024-02-01-19-47-41-855

  • m_f@midwest.social
    link
    fedilink
    arrow-up
    46
    arrow-down
    1
    ·
    edit-2
    9 months ago

    The collect’s in the middle aren’t necessary, neither is splitting by ": ". Here’s a simpler version

    fn main() {
        let text = "seeds: 79 14 55 13\nwhatever";
        let seeds: Vec<_> = text
            .lines()
            .next()
            .unwrap()
            .split_whitespace()
            .skip(1)
            .map(|x| x.parse::<u32>().unwrap())
            .collect();
        println!("seeds: {:?}", seeds);
    }
    

    It is simpler to bang out a [int(num) for num in text.splitlines()[0].split(' ')[1:]] in Python, but that just shows the happy path with no error handling, and does a bunch of allocations that the Rust version doesn’t. You can also get slightly fancier in the Rust version by collecting into a Result for more succinct error handling if you’d like.

    EDIT: Here’s also a version using anyhow for error handling, and the aforementioned Result collecting:

    use anyhow::{anyhow, Result};
    
    fn main() -> Result<()> {
        let text = "seeds: 79 14 55 13\nwhatever";
        let seeds: Vec<u32> = text
            .lines()
            .next()
            .ok_or(anyhow!("No first line!"))?
            .split_whitespace()
            .skip(1)
            .map(str::parse)
            .collect::<Result<_, _>>()?;
        println!("seeds: {:?}", seeds);
        Ok(())
    }
    
    • MaliciousKebab@sh.itjust.worksOP
      link
      fedilink
      English
      arrow-up
      6
      ·
      9 months ago

      Yeah I was trying to do something like reading the first line by getting an iterator and just looping through the other lines normally, since first line was kind of a special case but it got messy quick. I realized halfway that my collects were redundant but couldn’t really simplify it. Thanks

    • lad@programming.dev
      link
      fedilink
      arrow-up
      2
      ·
      edit-2
      9 months ago

      Also, anyhow::Context provides a convenient way to turn Option<T> and Result<T, Into<anyhow::Error>> into anyhow::Result<T>

      Like this:

      use anyhow::Context;
      
      // to my understanding it's better to 
      // specify the types when their names 
      // are the same as in prelude to improve
      // readability and reduce name clashing
      fn main() -> anyhow::Result<()> {
          let text = "seeds: 79 14 55 13\nwhatever";
          let seeds: Vec<u32> = text
              .lines()
              .next()
              .context("No first line!")?     // This line has changed
              .split_whitespace()
              .skip(1)
              .map(str::parse)
              .collect::<Result<_, _>>()?;
          println!("seeds: {:?}", seeds);
          Ok(())
      }
      

      Edit: line breaks