Skip to content

Instantly share code, notes, and snippets.

@gwpl
Created July 12, 2021 11:04
Show Gist options
  • Save gwpl/ad304ff3d6c72a335aafbf6c85ff5e5c to your computer and use it in GitHub Desktop.
Save gwpl/ad304ff3d6c72a335aafbf6c85ff5e5c to your computer and use it in GitHub Desktop.
#![allow(dead_code)]
// playground: https://gist.github.com/rust-play/6d697a29901d4b82cc8b184526d4b8f1
fn all_postfixes_sorted(arr: &[&str]) -> Vec<String> {
let mut postfixes: std::collections::HashSet<String> = std::collections::HashSet::new();
for &w in arr {
for start_idx in 0..(w.chars().count()) {
let slice: &str = &w[start_idx..];
let w = String::from(slice);
postfixes.insert(w);
}
}
let mut r = postfixes.into_iter().collect::<Vec<String>>();
r.sort();
r
}
fn filter_array_by_contains(arr_a: &[&str], arr_b: &[&str]) -> Vec<String> {
let postfixes = all_postfixes_sorted(arr_b);
let pred = |x: &&str| -> Option<String> {
let idx = postfixes.partition_point(|y| *y < x.to_string());
eprintln!("postfixes[idx] = '{:?} vs '{:?}' ", postfixes[idx], x);
if postfixes[idx].contains(x) {
Some(x.to_string())
} else {
None
}
};
arr_a
.iter()
.filter_map(pred)
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn examples() {
assert_eq!(filter_array_by_contains(
&["xyz", "live", "strong"],
&["lively", "alive", "harp", "sharp", "armstrong"],
), ["live", "strong"]);
assert_eq!(filter_array_by_contains(
&["live", "strong", "arp"],
&["lively", "alive", "harp", "sharp", "armstrong"],
), ["live", "strong", "arp"]);
assert_eq!(filter_array_by_contains(
&["tarp", "mice", "bull"],
&["lively", "alive", "harp", "sharp", "armstrong"],
), [] as [&str; 0]);
assert_eq!(filter_array_by_contains(
&["live", "strong", "arp", "arp"],
&["lively", "alive", "harp", "sharp", "armstrong"],
), ["live", "strong", "arp", "arp"]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment