|
|
|
@ -0,0 +1,101 @@
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
println!("{:?}", word_frequency("hello world"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn word_frequency(sentence: &str) -> Vec<(String, u32)> {
|
|
|
|
|
let mut words: Vec<(String, u32)> = sentence
|
|
|
|
|
.split_whitespace()
|
|
|
|
|
.map(|x| x.to_lowercase())
|
|
|
|
|
.map(|x| x.chars().filter(|c| c.is_alphabetic()).collect::<String>())
|
|
|
|
|
.filter(|x| !x.is_empty())
|
|
|
|
|
.fold(HashMap::new(), |mut map, word| {
|
|
|
|
|
map.entry(word)
|
|
|
|
|
.and_modify(|count| *count += 1)
|
|
|
|
|
.or_insert(1u32);
|
|
|
|
|
map
|
|
|
|
|
})
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|(word, count)| (word.clone(), *count))
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
words.sort_by(|(a, _), (b, _)| a.cmp(b));
|
|
|
|
|
|
|
|
|
|
words
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod test {
|
|
|
|
|
|
|
|
|
|
use crate::word_frequency;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn basic_case() {
|
|
|
|
|
let input = "The quick brown fox, the quick Brown FOX!";
|
|
|
|
|
let expected = vec![
|
|
|
|
|
("brown".to_string(), 2),
|
|
|
|
|
("fox".to_string(), 2),
|
|
|
|
|
("quick".to_string(), 2),
|
|
|
|
|
("the".to_string(), 2),
|
|
|
|
|
];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn empty_string() {
|
|
|
|
|
let input = "";
|
|
|
|
|
let expected: Vec<(String, u32)> = vec![];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn only_punctuation() {
|
|
|
|
|
let input = ".,!?;:-";
|
|
|
|
|
let expected: Vec<(String, u32)> = vec![];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn single_word() {
|
|
|
|
|
let input = "hello";
|
|
|
|
|
let expected = vec![("hello".to_string(), 1)];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn multiple_spaces_and_punctuation() {
|
|
|
|
|
let input = "hello,,, world!!! HELLO.";
|
|
|
|
|
let expected = vec![("hello".to_string(), 2), ("world".to_string(), 1)];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn numbers_and_mixed_chars() {
|
|
|
|
|
let input = "test123 test 123test TEST!";
|
|
|
|
|
// let expected = vec![("test".to_string(), 3)]; // 3? For sure?
|
|
|
|
|
let expected = vec![("test".to_string(), 4)];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn hyphenated_words() {
|
|
|
|
|
let input = "well-known well-Known WELL-KNOWN";
|
|
|
|
|
let expected = vec![("wellknown".to_string(), 3)];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn apostrophes_in_words() {
|
|
|
|
|
let input = "don't Don'T cant can't";
|
|
|
|
|
let expected = vec![("cant".to_string(), 2), ("dont".to_string(), 2)];
|
|
|
|
|
assert_eq!(word_frequency(input), expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn unicode_words() {
|
|
|
|
|
let input = "café CAFÉ résumé Résumé";
|
|
|
|
|
let expected = vec![("café".to_string(), 2), ("résumé".to_string(), 2)];
|
|
|
|
|
assert_eq!(word_frequency(input), expected)
|
|
|
|
|
}
|
|
|
|
|
}
|