Reputation: 89
I have to following piece of code that will have to find groups by comparing different vector elements:
fn main() {
let data = vec![
vec!["EG 1", "EG 2", "EG 3"],
vec!["XG 1", "XG 3"],
vec!["SG 1", "SG 6", "SG 8"],
vec!["PS 1", "PS 8"],
];
let result = Vec::<Vec<&str>>::new();
//
// element1.split_whitespace().last() == element2.split_whitespace().last()
//
assert_eq!(
vec![
vec!["EG 1", "XG 1", "PS 1", "SG 1"],
vec!["EG 2"],
vec!["XG 3", "EG 3"],
vec!["SG 6"],
vec!["SG 8", "PS 8"]
],
result
);
}
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7101df9439dd9cdff9f4b36c99a4efc6
As I commented out, I'd like to use the trailing number for comparing the elements:
element1.split_whitespace().last() == element2.split_whitespace().last()
I'm thinking of changing it in the future to use some library like fuzzywuzzy-rs but it's OK to compare as above for testing the algorithm.
I couldn't construct the loop properly and I have two issues that I'd like to point out:
mut
in this case. I'm not sure if it's a good idea either.retain
, map
etc.) but I'm not sure how.Upvotes: 0
Views: 774
Reputation: 5575
If you'd want to group elements, I would opt for a map-like structure.
The following seems to be what you're after:
use std::collections::BTreeMap;
fn main() {
let data = vec![
vec!["EG 1", "EG 2", "EG 3"],
vec!["XG 1", "XG 3"],
vec!["SG 1", "SG 6", "SG 8"],
vec!["PS 1", "PS 8"],
];
let mut result = BTreeMap::<usize, Vec<String>>::new();
for values in data.iter() {
for &s in values.iter() {
let id = s.split_whitespace()
.last()
.map(|s| s.parse::<usize>().unwrap())
.unwrap();
result.entry(id).or_default().push(s.to_owned());
}
}
println!("{:?}", result.values());
}
Using BTreeMap::values
you can then get the values back out into a Vec
, ordered by their key:
[
[ "EG 1", "XG 1", "SG 1", "PS 1" ],
[ "EG 2" ],
[ "EG 3", "XG 3" ],
[ "SG 6" ],
[ "SG 8", "PS 8" ],
]
Upvotes: 1
Reputation: 3057
You need something like that:
fn main() {
let data = vec![
vec!["EG 1", "EG 2", "EG 3"],
vec!["XG 1", "XG 3"],
vec!["SG 1", "SG 6", "SG 8"],
vec!["PS 1", "PS 8"],
];
let mut map = std::collections::HashMap::new();
for vv in data.iter(){
for v in vv.iter().copied(){
let k = v.split(" ").nth(1).unwrap();
map.entry(k).or_insert(Vec::new()).push(v);
}
}
let result: Vec<_> = {
let mut result: Vec<(&str, Vec<_>)> = map.into_iter().collect();
result.sort_by(|a, b|a.0.cmp(b.0));
result.into_iter().map(|(_, v)|v).collect()
};
}
Upvotes: 0