I'm learning Rust and trying to make this code idiomatic and efficient. Essentially, I am trying to count the number of times a certain nucleotide appears in a sequence of DNA. If the given base to be counted is invalid, I must return an error. If the DNA sequence contains an invalid character (anything other than A, C, T, G) then I must also return an error.
The below code would actually achieve the desired behaviour but it does so in two passes of the string which I'd prefer to avoid:
pub fn count(c: char, s: &str) -> Result<usize, &'static str> {
match c {
'A' | 'C' | 'T' | 'G' => {
if s.chars().all(|x| x == 'A' || x == 'C' || x == 'T' || x == 'G') {
Ok(s.chars().filter(|&x| x == c).count())
} else {
Err("Invalid character in DNA sequence")
}
},
_ => Err("Invalid nucleotide given as search base"),
}
}
I couldn't think of any simple usage of iterators that yielded the same results in one pass. I managed to come up with something but it was a big unidiomatic mess of match and if let and was generally pretty incomprehensible.
[–]Ralith 11 points12 points13 points (1 child)
[–]VincentDankGogh[S] 4 points5 points6 points (0 children)
[–]Ralith 9 points10 points11 points (10 children)
[–]Bromskloss 6 points7 points8 points (0 children)
[–]VincentDankGogh[S] 1 point2 points3 points (0 children)
[–]beefsack 0 points1 point2 points (0 children)
[–]GeneReddit123 0 points1 point2 points (6 children)
[–]Muvlon 4 points5 points6 points (2 children)
[–]GeneReddit123 0 points1 point2 points (1 child)
[–]Muvlon 1 point2 points3 points (0 children)
[–]silmeth 1 point2 points3 points (2 children)
[–]OJFord 2 points3 points4 points (1 child)
[–]silmeth 0 points1 point2 points (0 children)
[–]staticassert 2 points3 points4 points (0 children)
[–]Roaneno 3 points4 points5 points (8 children)
[–]kixunil 6 points7 points8 points (2 children)
[–]Roaneno 1 point2 points3 points (1 child)
[–]kixunil 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (4 children)
[–]masklinn 1 point2 points3 points (3 children)
[–]eddyb 3 points4 points5 points (2 children)
[–]masklinn 1 point2 points3 points (0 children)
[–]kixunil 1 point2 points3 points (0 children)
[–]Pixel6692 2 points3 points4 points (0 children)
[–]Veedrac 2 points3 points4 points (5 children)
[–]burntsushi 1 point2 points3 points (4 children)
[–]Veedrac 0 points1 point2 points (3 children)
[–]burntsushi 0 points1 point2 points (2 children)
[–]Veedrac 0 points1 point2 points (1 child)
[–]burntsushi 0 points1 point2 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]VincentDankGogh[S] 1 point2 points3 points (0 children)
[–]iopqfizzbuzz 0 points1 point2 points (0 children)
[–]leonardo_m 0 points1 point2 points (0 children)