pkg/eval: Make the sorting of "order" always stable.

This commit is contained in:
Qi Xiao 2020-05-25 21:50:09 +01:00
parent 1cd192daaf
commit ff292d43ce
2 changed files with 8 additions and 15 deletions

View File

@ -634,16 +634,14 @@ func keys(fm *Frame, v interface{}) error {
//elvdoc:fn order
//
// ```elvish
// order &reverse=$false &stable=$false $less-than=$nil~ $inputs?
// order &reverse=$false $less-than=$nil $inputs?
// ```
//
// Outputs the input values sorted in ascending order.
// Outputs the input values sorted in ascending order. The sort is guaranteed to
// be [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
//
// The `&reverse` option, if true, reverses the order of output.
//
// The `&stable` option, if true, makes the sort
// [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
//
// The `&less-than` option, if given, establishes the ordering of the elements.
// Its value should be a function that takes two arguments and outputs a single
// boolean indicating whether the first argument is less than the second
@ -685,7 +683,7 @@ func keys(fm *Frame, v interface{}) error {
// ▶ c
// ▶ b
// ▶ a
// ~> order &less-than=[a b]{ eq $a x } &stable [l x o r x e x m]
// ~> order &less-than=[a b]{ eq $a x } [l x o r x e x m]
// ▶ x
// ▶ x
// ▶ x
@ -712,7 +710,6 @@ func keys(fm *Frame, v interface{}) error {
type orderOptions struct {
Reverse bool
Stable bool
LessThan Callable
}
@ -779,11 +776,7 @@ func order(fm *Frame, opts orderOptions, inputs Inputs) error {
}
}
if opts.Stable {
sort.SliceStable(values, lessFn)
} else {
sort.Slice(values, lessFn)
}
sort.SliceStable(values, lessFn)
if errSort != nil {
return errSort

View File

@ -136,9 +136,9 @@ func TestBuiltinFnContainer(t *testing.T) {
// &less-than and &reverse
That("put 1 10 2 5 | order &reverse &less-than=[a b]{ < $a $b }").
Puts("10", "5", "2", "1"),
// &stable - test by pretending that all values but one are equal, and
// check that the order among them has not changed
That("put l x o x r x e x m | order &stable &less-than=[a b]{ eq $a x }").
// Sort should be stable - test by pretending that all values but one d
// are equal, an check that the order among them has not change d
That("put l x o x r x e x m | order &less-than=[a b]{ eq $a x }").
Puts("x", "x", "x", "x", "l", "o", "r", "e", "m"),
)
}