Skip to content

Instantly share code, notes, and snippets.

@akiradeveloper
Created June 22, 2014 09:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akiradeveloper/3c42a44ca492e7224233 to your computer and use it in GitHub Desktop.
Save akiradeveloper/3c42a44ca492e7224233 to your computer and use it in GitHub Desktop.
let v1 = vec!["b", "C", "l"];
let v2 = v1.iter().map(|x| matches.opt_str(*x));
let n = v2.filter(|ref x| x.is_none()).count();
if n > 1 {
crash!(1, "{}: cannot split in more than one way", NAME);
} else if n == 1 {
let e = v2.find(|ref x| !x.is_none()).unwrap(); // error
}
@akiradeveloper
Copy link
Author

Great advice

akiradeveloper What's wrong with my code?
18:07 eddyb akiradeveloper: let mut v2
18:08 akiradeveloper But I don't need the mutability for filter, right?
18:08 eddyb though, what you're doing isn't really great, algorithmically
18:08 eddyb akiradeveloper: filter moves the iterator
18:08 akiradeveloper what? so I am doing wrong...?
18:09 eddyb you're counting and finding, and even if the code compiled, those would be two traversals
18:09 eddyb you're using n, but you don't need the value for the actual logic
18:10 eddyb let mut v2 = v1.iter().filter_map(|x| matches.opt_str(x)); let (first, second) = (v2.next(), v2.next());
18:10 *
* dzhulk quit (Ping timeout)
18:10 *** dzhulk joined #rust
18:10 eddyb n > 1 becomes second.is_some(), I'm guessing
18:11 eddyb and n == 1 is first.is_some(), but you're likely going to match on first and/or second anyways
18:11 akiradeveloper yes
18:11 *** Romster joined #rust
18:11 akiradeveloper There is a case that n == 0
18:11 eddyb that would be first.is_none()
18:12 eddyb you can probably match (v2.next(), v2.next()) directly
18:13 akiradeveloper I see. That would be smarter
18:13 eddyb (None, ), (Some(e), None) and (Some(), Some())
18:13 eddyb well, the last one should be (
, Some()) since the compiler can't tell (None, Some()) is not going to happen
18:16 akiradeveloper ah, you said my code is not efficient because it traverses twice?

@akiradeveloper
Copy link
Author

Works...

I want to know a manner of duplicating v2 or revert the v2 iterator back

    let v1 = vec!["b", "C", "l"];
    let mut v2 = v1.iter().map(|x| matches.opt_str(*x)).filter(|ref x| !x.is_none());
    let n =  v2.count();
    if n > 1 {
            crash!(1, "{}: cannot split in more than one way", NAME);
    } else if n == 1 {
            let mut v3 = v1.iter().map(|x| matches.opt_str(*x)).filter(|ref x| !x.is_none());
            let e = v3.find(|ref x| !x.is_none()).unwrap();
            println!("{}", e);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment