Joinable traits
I just released an update to my joinable
crate (source code here) as well as a new irisdata
crate (source code) well-known in the data science field.
This update to joinable
renames the Joinable
trait to JoinableGrouped
to reflect that the results (at least of inner- and outer-joins) group the right-hand side. It also adds a new trait with the Joinable
name that behaves perhaps more intuitively – each left-hand record can be yielded multiple times (as matches are found).
Joinable
only defines inner_join
and outer_join
methods. JoinableGrouped
defines inner_join_grouped
, outer_join_grouped
, semi_join
, and anti_join
.
use std::cmp::Ordering;
use irisdata::{Species, IRIS_DATA};
use joinable::{JoinableGrouped, RHS};
#[derive(Debug)]
struct IrisData {
species: Species,
common_name: &'static str,
average_sepal_length: f32,
average_sepal_width: f32,
average_petal_length: f32,
average_petal_width: f32,
}
fn main() {
let common_names = [
(Species::IrisVersicolor, "blue flag"),
(Species::IrisVersicolor, "harlequin blueflag"),
(Species::IrisVersicolor, "larger blue flag"),
(Species::IrisVersicolor, "northern blue flag"),
(Species::IrisVersicolor, "poison flag"),
(Species::IrisVirginica, "Virginia blueflag"),
(Species::IrisVirginica, "Virginia iris"),
(Species::IrisVirginica, "great blue flag"),
(Species::IrisVirginica, "southern blue flag"),
];
let joined = common_names
.iter()
.inner_join_grouped(RHS::new_unsorted(&IRIS_DATA[..]), |(lhs_species, _), r| {
if *lhs_species == r.species {
Ordering::Equal
} else {
Ordering::Less
}
})
.map(|(lhs, grp)| IrisData {
species: lhs.0,
common_name: lhs.1,
average_sepal_length: grp.iter().map(|i| i.sepal_length).sum::<f32>() / grp.len() as f32,
average_sepal_width: grp.iter().map(|i| i.sepal_width).sum::<f32>() / grp.len() as f32,
average_petal_length: grp.iter().map(|i| i.petal_length).sum::<f32>() / grp.len() as f32,
average_petal_width: grp.iter().map(|i| i.petal_width).sum::<f32>() / grp.len() as f32,
})
.collect::<Vec<_>>();
println!("{joined:#?}");
}