rust sort
use std::cmp::Ordering; enum Fruit { Apple(i32), Orange(i32), } fn process_fruit(_apple_prices: &[i32], _orange_prices: &[i32]) { // whatever we do to process fruit, does not matter } fn main() { let mut fruit : Vec<Fruit> = vec![Fruit::Apple(1), Fruit::Apple(2), Fruit::Orange(4), Fruit::Orange(3), ]; /* * Sort fruit by some crazy function - let's say we value oranges more * than apples, so when we compare one to the other, we increase * the price of oranges by 10. */ let fruit_comparator = |x: &Fruit, y: &Fruit| match(x, y) { (Fruit::Apple(lhs), Fruit::Apple(rhs)) => { lhs.cmp(rhs) }, (Fruit::Apple(lhs), Fruit::Orange(rhs)) => { lhs.cmp(&(*rhs + 10)) }, (Fruit::Orange(lhs), Fruit::Apple(rhs)) => { (lhs + 10).cmp(rhs) }, (Fruit::Orange(lhs), Fruit::Orange(rhs)) => { lhs.cmp(rhs) }, }; fruit.sort_by(fruit_comparator); // apples must __only__ contain Fruit::Apple variants let mut apple_prices : Vec<i32> = vec![]; // oranges must __only__ contain Fruit::Orange variants let mut orange_prices : Vec<i32> = vec![]; // TODO generate `fruit_grouped` from an existing sorted `fruit` let fruit_sorted_by_price_grouped : Vec<Vec<Fruit>> = { let mut groups = Vec::new(); let mut this_group = Vec::new(); for f in fruit { if this_group.is_empty() || fruit_comparator(&this_group[0], &f) == Ordering::Equal { this_group.push(f); } else { groups.push(this_group); this_group = vec![f]; } } groups }; for i in fruit_sorted_by_price_grouped { for j in i { match j { Fruit::Apple(price) => { apple_prices.push(price); } Fruit::Orange(price) => { orange_prices.push(price); } }; process_fruit(&apple_prices, &orange_prices); apple_prices = vec![]; orange_prices = vec![]; } } }