diff --git a/src/cmd/sort.rs b/src/cmd/sort.rs index f1f938641..616f05f00 100644 --- a/src/cmd/sort.rs +++ b/src/cmd/sort.rs @@ -4,8 +4,8 @@ use crate::config::{Config, Delimiter}; use crate::select::SelectColumns; use crate::util; use crate::CliResult; +use rand::{seq::SliceRandom, SeedableRng, rngs::StdRng}; use serde::Deserialize; -use rand::{thread_rng, Rng, SeedableRng, StdRng}; use std::str::from_utf8; use self::Number::{Float, Int}; @@ -46,7 +46,7 @@ struct Args { flag_numeric: bool, flag_reverse: bool, flag_random: bool, - flag_seed: Option, + flag_seed: Option, flag_output: Option, flag_no_headers: bool, flag_delimiter: Option, @@ -70,45 +70,39 @@ pub fn run(argv: &[&str]) -> CliResult<()> { // Seeding rng let seed = args.flag_seed; - let mut rng: StdRng = match seed { - None => { - StdRng::from_rng(thread_rng()).unwrap() - } - Some(seed) => { - let mut buf = [0u8; 32]; - LittleEndian::write_u64(&mut buf, seed as u64); - SeedableRng::from_seed(buf) - } - }; let mut all = rdr.byte_records().collect::, _>>()?; match (numeric, reverse, random) { - (_, _, true) => - rng.shuffle(&mut all), - (false, false, false) => - all.sort_by(|r1, r2| { - let a = sel.select(r1); - let b = sel.select(r2); - iter_cmp(a, b) - }), - (true, false, false) => - all.sort_by(|r1, r2| { - let a = sel.select(r1); - let b = sel.select(r2); - iter_cmp_num(a, b) - }), - (false, true, false) => - all.sort_by(|r1, r2| { - let a = sel.select(r1); - let b = sel.select(r2); - iter_cmp(b, a) - }), - (true, true, false) => - all.sort_by(|r1, r2| { - let a = sel.select(r1); - let b = sel.select(r2); - iter_cmp_num(b, a) - }), + (_, _, true) => { + //SliceRandom::shuffle(&mut all, &mut rng), + if let Some(val) = seed { + let mut rng = StdRng::seed_from_u64(val); + SliceRandom::shuffle(&mut *all, &mut rng); + } else { + let mut rng = ::rand::thread_rng(); + SliceRandom::shuffle(&mut *all, &mut rng); + } + } + (false, false, false) => all.sort_by(|r1, r2| { + let a = sel.select(r1); + let b = sel.select(r2); + iter_cmp(a, b) + }), + (true, false, false) => all.sort_by(|r1, r2| { + let a = sel.select(r1); + let b = sel.select(r2); + iter_cmp_num(a, b) + }), + (false, true, false) => all.sort_by(|r1, r2| { + let a = sel.select(r1); + let b = sel.select(r2); + iter_cmp(b, a) + }), + (true, true, false) => all.sort_by(|r1, r2| { + let a = sel.select(r1); + let b = sel.select(r2); + iter_cmp_num(b, a) + }), } let mut wtr = Config::new(&args.flag_output).writer()?; diff --git a/tests/test_sort.rs b/tests/test_sort.rs index 7d2c01b0c..79abc912d 100644 --- a/tests/test_sort.rs +++ b/tests/test_sort.rs @@ -170,20 +170,31 @@ fn sort_uniq() { #[test] fn sort_random() { let wrk = Workdir::new("sort_random"); - wrk.create("in.csv", vec![ - svec!["R", "S"], - svec!["1", "b"], - svec!["2", "a"], - ]); + wrk.create( + "in.csv", + vec![ + svec!["R", "S"], + svec!["1", "b"], + svec!["2", "a"], + svec!["3", "d"], + svec!["4", "c"], + svec!["5", "f"], + svec!["6", "e"], + ], + ); let mut cmd = wrk.command("sort"); - cmd.arg("--random").args(&["--seed", "0"]).arg("in.csv"); + cmd.arg("--random").args(&["--seed", "42"]).arg("in.csv"); let got: Vec> = wrk.read_stdout(&mut cmd); let expected = vec![ svec!["R", "S"], - svec!["2", "a"], svec!["1", "b"], + svec!["5", "f"], + svec!["6", "e"], + svec!["3", "d"], + svec!["2", "a"], + svec!["4", "c"], ]; assert_eq!(got, expected); }