Hacker News new | ask | show | jobs
by general_pizza 2687 days ago
I also thought regex seemed overkill and didn't feel like adding an extra crate to my Cargo.toml. Luckily for the days I attempted I was able to get by on just the split method for str's[0] which was nice and concise. So for your regex example you could also do:

    // #1 @ 916,616: 21x29
    let parts: Vec<&str> = l.split(['@', ',', ':', 'x'].as_ref()).collect();
    let x = parts[1].trim().parse::<i32>().expect("x as i32");
    let y = parts[2].trim().parse::<i32>().expect("y as i32");
    let w = parts[3].trim().parse::<i32>().expect("width as i32");
    let h = parts[4].trim().parse::<i32>().expect("height as i32");
[0] https://doc.rust-lang.org/std/primitive.str.html#method.spli...
3 comments

The next step could be to remove `.collect()` and use `.next()` for each subsequent part. Zero allocations!

    let mut parts = l.split(&['@', ',', ':', 'x'][..])
       .flat_map(|s| s.trim().parse::<i32>().ok());
    let x = parts.next().expect("x as i32");
    let y = parts.next().expect("y as i32");
    let w = parts.next().expect("width as i32");
    let h = parts.next().expect("height as i32");
> and didn't feel like adding an extra crate to my Cargo.toml

Why not? cargo makes it extremely easy to add new crates. The hardest part is figuring out what dependency you want, but once you know what it is, adding it is really easy.

Totally agree, cargo makes it easy. Honestly it’s just that the level of laziness is so high when I’m programming on something personal after work that even having to switch to chrome to check a version number on crates.io will be avoided.
You might be interested to know that cargo can do that for you

  $ cargo search regex
  regex = "1.1.0"             # An implementation of regular expressions for Rust. This implementation uses finite automata and gua…
  regex-automata = "0.1.5"    # Automata construction and matching using regular expressions.
  …
This is awesome. How did you figure this out? The documentation on `split` says:

"The pattern can be a &str, char, or a closure that determines the split."

But in your case it is an array of chars and it splits for each of them. I don't see this documented at all.

The docs are a tad misleading but the important piece is to look at the signature. The `where P: Pattern<'a>` portion states that split needs a type that implements the Pattern trait. If you follow the link to the Pattern trait then at the bottom you'll see a section[0] listing types implementing the trait (&[char] being one) and therefore can be passed into split. Hope that helps!

[0] https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html...

Would you be willing to file a docs bug so we can clarify this?

It’s possible that it used to be only those types, but was expanded. We should fix this!

Yeah, will do
Awesome, thank you!
Vec<char> or an array for instance - [char; 20] can (automatically) create a "slice" of type &[char]. This is true for all types (not just char).

The operator for this is for eg l[1..10]. It can also happen automatically.

&str is the same type as &[char] - just a renaming.

Still learning Rust myself, apologies if this leads you astray. Just do some reading on slices.

https://doc.rust-lang.org/book/ch04-03-slices.html#string-sl...

https://doc.rust-lang.org/std/slice/

&str is not the same as &[char]. &str has the same memory representation as &[u8]. char is four bytes, not one.
Thanks Steve.
No problem! It's an easy mistake to make.