mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 01:38:04 +00:00
Merge pull request #932 from alsuren/sort--stable
implement sort --stable
This commit is contained in:
commit
63c17e5b42
6 changed files with 66 additions and 6 deletions
|
@ -43,6 +43,7 @@ struct Settings {
|
|||
mode: SortMode,
|
||||
reverse: bool,
|
||||
outfile: Option<String>,
|
||||
stable: bool,
|
||||
unique: bool,
|
||||
check: bool,
|
||||
}
|
||||
|
@ -53,6 +54,7 @@ impl Default for Settings {
|
|||
mode: SortMode::Default,
|
||||
reverse: false,
|
||||
outfile: None,
|
||||
stable: false,
|
||||
unique: false,
|
||||
check: false,
|
||||
}
|
||||
|
@ -70,6 +72,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
opts.optflag("h", "help", "display this help and exit");
|
||||
opts.optflag("", "version", "output version information and exit");
|
||||
opts.optopt("o", "output", "write output to FILENAME instead of stdout", "FILENAME");
|
||||
opts.optflag("s", "stable", "stabilize sort by disabling last-resort comparison");
|
||||
opts.optflag("u", "unique", "output only the first of an equal run");
|
||||
opts.optflag("V", "version-sort", "Sort by SemVer version number, eg 1.12.2 > 1.1.2");
|
||||
opts.optflag("c", "check", "check for sorted input; do not sort");
|
||||
|
@ -112,6 +115,7 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION);
|
|||
|
||||
settings.reverse = matches.opt_present("reverse");
|
||||
settings.outfile = matches.opt_str("output");
|
||||
settings.stable = matches.opt_present("stable");
|
||||
settings.unique = matches.opt_present("unique");
|
||||
settings.check = matches.opt_present("check");
|
||||
|
||||
|
@ -146,14 +150,25 @@ fn exec(files: Vec<String>, settings: &Settings) -> i32 {
|
|||
|
||||
let original_lines = lines.to_vec();
|
||||
|
||||
match settings.mode {
|
||||
SortMode::Numeric => lines.sort_by(numeric_compare),
|
||||
SortMode::HumanNumeric => lines.sort_by(human_numeric_size_compare),
|
||||
SortMode::Month => lines.sort_by(month_compare),
|
||||
SortMode::Version => lines.sort_by(version_compare),
|
||||
SortMode::Default => lines.sort()
|
||||
let mut compare_fns = Vec::new();
|
||||
|
||||
compare_fns.push(match settings.mode {
|
||||
SortMode::Numeric => numeric_compare,
|
||||
SortMode::HumanNumeric => human_numeric_size_compare,
|
||||
SortMode::Month => month_compare,
|
||||
SortMode::Version => version_compare,
|
||||
SortMode::Default => String::cmp
|
||||
});
|
||||
|
||||
if !settings.stable {
|
||||
match settings.mode {
|
||||
SortMode::Default => {}
|
||||
_ => compare_fns.push(String::cmp)
|
||||
}
|
||||
}
|
||||
|
||||
sort_by(&mut lines, compare_fns);
|
||||
|
||||
if settings.unique {
|
||||
lines.dedup()
|
||||
}
|
||||
|
@ -178,6 +193,20 @@ fn exec(files: Vec<String>, settings: &Settings) -> i32 {
|
|||
|
||||
}
|
||||
|
||||
fn sort_by<F>(lines: &mut Vec<String>, compare_fns: Vec<F>)
|
||||
where F: Fn( &String, &String ) -> Ordering
|
||||
{
|
||||
lines.sort_by(|a, b| {
|
||||
for compare_fn in &compare_fns {
|
||||
let cmp = compare_fn(a, b);
|
||||
if cmp != Ordering::Equal {
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
return Ordering::Equal;
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse the beginning string into an f64, returning -inf instead of NaN on errors.
|
||||
fn permissive_f64_parse(a: &str) -> f64 {
|
||||
// Maybe should be split on non-digit, but then 10e100 won't parse properly.
|
||||
|
|
3
tests/fixtures/sort/month_default.expected
vendored
3
tests/fixtures/sort/month_default.expected
vendored
|
@ -3,5 +3,8 @@ Jan Lorem ipsum dolor sit amet
|
|||
mar laboris nisi ut aliquip ex ea
|
||||
May sed do eiusmod tempor incididunt
|
||||
JUN nostrud exercitation ullamco
|
||||
Jul 1 should remain 2,1,3
|
||||
Jul 2 these three lines
|
||||
Jul 3 if --stable is provided
|
||||
Oct ut labore et dolore magna aliqua
|
||||
Dec consectetur adipiscing elit
|
||||
|
|
3
tests/fixtures/sort/month_default.txt
vendored
3
tests/fixtures/sort/month_default.txt
vendored
|
@ -5,3 +5,6 @@ Oct ut labore et dolore magna aliqua
|
|||
N/A Ut enim ad minim veniam, quis
|
||||
JUN nostrud exercitation ullamco
|
||||
mar laboris nisi ut aliquip ex ea
|
||||
Jul 2 these three lines
|
||||
Jul 1 should remain 2,1,3
|
||||
Jul 3 if --stable is provided
|
||||
|
|
10
tests/fixtures/sort/month_stable.expected
vendored
Normal file
10
tests/fixtures/sort/month_stable.expected
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
N/A Ut enim ad minim veniam, quis
|
||||
Jan Lorem ipsum dolor sit amet
|
||||
mar laboris nisi ut aliquip ex ea
|
||||
May sed do eiusmod tempor incididunt
|
||||
JUN nostrud exercitation ullamco
|
||||
Jul 2 these three lines
|
||||
Jul 1 should remain 2,1,3
|
||||
Jul 3 if --stable is provided
|
||||
Oct ut labore et dolore magna aliqua
|
||||
Dec consectetur adipiscing elit
|
10
tests/fixtures/sort/month_stable.txt
vendored
Normal file
10
tests/fixtures/sort/month_stable.txt
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
Jan Lorem ipsum dolor sit amet
|
||||
Dec consectetur adipiscing elit
|
||||
May sed do eiusmod tempor incididunt
|
||||
Oct ut labore et dolore magna aliqua
|
||||
N/A Ut enim ad minim veniam, quis
|
||||
JUN nostrud exercitation ullamco
|
||||
mar laboris nisi ut aliquip ex ea
|
||||
Jul 2 these three lines
|
||||
Jul 1 should remain 2,1,3
|
||||
Jul 3 if --stable is provided
|
|
@ -41,6 +41,11 @@ fn test_month_default() {
|
|||
test_helper("month_default", "-M");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_month_stable() {
|
||||
test_helper("month_stable", "-Ms");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_unsorted_ints() {
|
||||
test_helper("default_unsorted_ints", "");
|
||||
|
|
Loading…
Reference in a new issue