So this is my struct. As you can see it’s a composite struct (string and number/Decimal)
use rust_decimal::prelude::*;
#[derive(Deserialize, Serialize, Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct Row {
pub acc_code: String,
pub acc_type: String,
pub acc_name: String,
pub before: Decimal,
pub total: Decimal,
pub after: Decimal,
}
and this is how I sort an array (Vector) of this struct. I use the sort_by_key() method for vector:
let sort_by = Some("acc_code");
let container: Vec<Row> = vec![];
// sorting
match view_options.sort_by {
Some(sort_by) => {
container.sort_by_key(|r| match sort_by.as_ref() {
"acc_code" => r.acc_code.clone(),
"acc_type" => r.acc_type.clone(),
"acc_name" => r.acc_name.clone(),
"before" => r.before.to_string(), // this is the source of the problem
"after" => r.after.to_string(), // I can only use one of the type
"total" => r.total.to_string(), // either string or number here
_ => r.acc_code.clone(),
});
}
None => {}
}
this works as long as it only sort field with string type (acc_code, acc_type or acc_name).
If you sort the number field (like total, after or before), it only sort the first character of that number (since it is converted to a string), eg: [1000, 4, 500, 6]. Rust only sees the first character of that number and doesn’t consider the rest
I had to use string for sort_by_key to work since it requires unified output types. So either I convert the number into string or convert the string into number. So how do I give a numerical "value" into a string so it will sort properly across any field ?
>Solution :
Instead of using sort_by_key(), use sort_by():
container.sort_by(|a, b| match sort_by.as_ref() {
"acc_code" => a.acc_code.cmp(&b.acc_code),
"acc_type" => a.acc_type.cmp(&b.acc_type),
"acc_name" => a.acc_name.cmp(&b.acc_name),
"before" => a.before.cmp(&b.before),
"after" => a.after.cmp(&b.after),
"total" => a.kredit.cmp(&b.kredit),
_ => a.acc_code.cmp(&b.acc_code),
});