Kenny Grant has uploaded this change for review.
sort: new example: SliceStable examples to demonstrate sorting slices ExampleSliceStable echoes sort.Slice example, to demonstrate sorting on two fields at together. Example_sortSliceStable offers a shorter version of Example_sortMultiKeys using the new sort.SliceStable. Change-Id: I8afc20c0203991bfd57260431eda73913c165355 --- A src/sort/example_slice_stable_test.go M src/sort/example_test.go 2 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/src/sort/example_slice_stable_test.go b/src/sort/example_slice_stable_test.go
new file mode 100644
index 0000000..fc30981
--- /dev/null
+++ b/src/sort/example_slice_stable_test.go
@@ -0,0 +1,56 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sort_test
+
+import (
+ "fmt"
+ "sort"
+)
+
+// Person has a Name and an Age.
+type Person struct {
+ Name string
+ Age int
+}
+
+// PeopleSorter defines functions for sorting people on name and age.
+type PeopleSorter []Person
+
+func (p PeopleSorter) ByName(i, j int) bool {
+ return p[i].Name < p[j].Name
+}
+func (p PeopleSorter) ByAge(i, j int) bool {
+ return p[i].Age < p[j].Age
+}
+func (p PeopleSorter) Sort(functions ...func(i, j int) bool) {
+ for _, fn := range functions {
+ sort.SliceStable(p, fn)
+ }
+}
+
+// ExampleSliceStable demonstrates sorting a slice of structs by two fields
+// using sort.SliceStable.
+func Example_sortSliceStable() {
+
+ people := PeopleSorter{
+ {"Gopher", 55},
+ {"Alice", 55},
+ {"Alice", 23},
+ {"Vera", 23},
+ {"Bob", 56},
+ {"Ava", 2},
+ }
+
+ // Sort by name then age, so that age takes priority.
+ people.Sort(people.ByName, people.ByAge)
+ fmt.Println("Sorted by age,name:", people)
+
+ // Sort by age then name, so that name takes priority.
+ people.Sort(people.ByAge, people.ByName)
+ fmt.Println("Sorted by name,age:", people)
+
+ // Output: Sorted by age,name: [{Ava 2} {Alice 23} {Vera 23} {Alice 55} {Gopher 55} {Bob 56}]
+ // Sorted by name,age: [{Alice 23} {Alice 55} {Ava 2} {Bob 56} {Gopher 55} {Vera 23}]
+}
diff --git a/src/sort/example_test.go b/src/sort/example_test.go
index 980c0d0..87b0156 100644
--- a/src/sort/example_test.go
+++ b/src/sort/example_test.go
@@ -41,3 +41,24 @@
// Output: By name: [{Alice 55} {Bob 75} {Gopher 7} {Vera 24}]
// By age: [{Gopher 7} {Vera 24} {Alice 55} {Bob 75}]
}
+
+func ExampleSliceStable() {
+ people := []struct {
+ Name string
+ Age int
+ }{
+ {"Gopher", 7},
+ {"Goph", 17},
+ {"Alice", 55},
+ {"Alice", 51},
+ {"Vera", 24},
+ {"Bob", 75},
+ }
+ sort.SliceStable(people, func(i, j int) bool { return people[i].Name < people[j].Name })
+ fmt.Println("By name:", people)
+
+ sort.SliceStable(people, func(i, j int) bool { return people[i].Age < people[j].Age })
+ fmt.Println("By name, then by age:", people)
+ // Output: By name: [{Alice 55} {Alice 51} {Bob 75} {Goph 17} {Gopher 7} {Vera 24}]
+ // By name, then by age: [{Gopher 7} {Goph 17} {Vera 24} {Alice 51} {Alice 55} {Bob 75}]
+}
To view, visit change 37196. To unsubscribe, visit settings.
Kenny Grant uploaded patch set #2 to this change.
sort: new example: SliceStable examples to demonstrate sorting slices ExampleSliceStable echoes the sort.Slice example, to demonstrate sorting on two fields together rather than separately as in sort.Slice. Example_sortSliceStable offers a shorter version of Example_sortMultiKeys using the new sort.SliceStable and a slice type to sort on multiple keys. Change-Id: I8afc20c0203991bfd57260431eda73913c165355 --- A src/sort/example_slice_stable_test.go M src/sort/example_test.go 2 files changed, 77 insertions(+), 0 deletions(-)
To view, visit change 37196. To unsubscribe, visit settings.
Brad Fitzpatrick posted comments on this change.
Patch set 2:
(3 comments)
File src/sort/example_slice_stable_test.go:
Patch Set #2, Line 1: // Copyright 2013 The Go Authors. All rights reserved.
wrong year
Patch Set #2, Line 29: SliceStable
oh, there it is! That's a lot of example code to show sort.SliceStable. I think you can do it without all this machinery.
Just have three Alices aged 30 20 10 and sort.SliceStable on just name and show that they stay listed in 30 20 10 order.
No need for a PeopleSorter.
File src/sort/example_test.go:
Patch Set #2, Line 57: sort.SliceStable(people, func(i, j int) bool { return people[i].Name < people[j].Name })
oh, here's a minimal example.
I think this one is fine. What do you think we gain by having the gigantic one?
To view, visit change 37196. To unsubscribe, visit settings.
Kenny Grant uploaded patch set #3 to this change.
sort: new example: Sorting slices with sort.SliceStable ExampleSliceStable echoes the sort.Slice example, to demonstrate sorting on two fields together preserving order between sorts. ExampleMultiKeysStable demonstrates sorting on multiple keys using a slice wrapper which defines sort functions. Change-Id: I8afc20c0203991bfd57260431eda73913c165355 --- A src/sort/example_slice_stable_test.go M src/sort/example_test.go 2 files changed, 94 insertions(+), 0 deletions(-)
To view, visit change 37196. To unsubscribe, visit settings.
Kenny Grant posted comments on this change.
Patch set 2:
Patch Set 2: Oh, there it is!
A few notes on this which I hope will explain the motivation:
The simple example was intended as the illustration of sort.SliceStable.
I know you anticipated sort.SliceStable being used with inline functions, the more complex example was intended to replace example_multi_test - it does the same thing so I've tweaked it to make this clearer and use the same data. Personally now we have sort.SliceStable I would use that instead of the example_multi_test method using interfaces because:
1. Order is preserved (the example_multi_test does not do this, see the language,<lines sort). 2. It is shorter and clearer than example_multi_test 3. This shifts complexity over to the slice wrapper from the calling site (SortBy, sort funcs), so sorting becomes one line but is still clear.
Obviously if you use multiSorter once it's pointless, but if you had a slice wrapper anyway for the data, and sort it in several different places in this sort of way, and/or have complex sorting requirements which mean the inline sorting functions would get ugly, it would be handy.
I wasn't sure if you'd want to get rid of the multi_test, but I wonder if it's no longer necc. because of the addition of sort.SliceStable, which can do the same thing in a simpler way as seen here. I hope this helps clarify a bit - example_multi_test could maybe be replaced by this method.
Kenny Grant uploaded patch set #4 to this change.
sort: new example: Sorting slices with sort.SliceStable ExampleSliceStable echoes the sort.Slice example, to demonstrate sorting on two fields together preserving order between sorts. Change-Id: I8afc20c0203991bfd57260431eda73913c165355 --- M src/sort/example_test.go 1 file changed, 21 insertions(+), 0 deletions(-)
To view, visit change 37196. To unsubscribe, visit settings.
Kenny Grant posted comments on this change.
Patch set 4:
Uploaded patch set 4.
I've removed the larger example for now, to make this easier to review. Hopefully the smaller SliceStable example is fine to merge as is.
Let me know if it is worth submitting a change to example_multi_test - I think now that we have slice.Sort... we should have an example at the top of the docs which uses that (as well as example_keys_test which uses Len/Swap/Less), but if you'd rather not I can just drop it.
(1 comment)
wrong year
Done
To view, visit change 37196. To unsubscribe, visit settings.
Volker Dobler posted comments on this change.
Patch set 4:
(3 comments)
File src/sort/example_test.go:
Patch Set #4, Line 57: sort.SliceStable(people, func(i, j int) bool { return people[i].Name < people[j].Name })
The example is not a good one: Sorting unstable with sort.Slice yields the same result. It will be hard to come up with a small example which does not only show the calling convention of SliceStable but its behaviour in contrast to Sort.
Patch Set #4, Line 60: sort.SliceStable(people, func(i, j int) bool { return people[i].Age < people[j].Age })
Stable sorting people by Age where all Ages are distinct is pretty useless: A normal (unstable) Sort would produce the exact same output. The nice thing about stable sorting is that you can sort twice (as you do here by Name and by Age) and the relative order generated by the first sorting is kept during the second sorting: The final result will be Age-sorted but each same-Age-block will be sorted alphabetically by Name. To show this nice feature you need an input set with several multiple Age values. Probably something like three Names times three Ages.
Patch Set #4, Line 62: // Output: By name: [{Alice 55} {Alice 51} {Bob 75} {Goph 17} {Gopher 7} {Vera 24}]
Is there a reason to not start a new line after Output: ? (For single line outputs a single "Output: <whatever>" line is fine but it seems odd for multi line expected output.)
To view, visit change 37196. To unsubscribe, visit settings.
Kenny Grant uploaded patch set #5 to this change.
sort: new example: Sorting slices with sort.SliceStable ExampleSliceStable echoes the sort.Slice example, to demonstrate sorting on two fields together preserving order between sorts. Change-Id: I8afc20c0203991bfd57260431eda73913c165355 --- M src/sort/example_test.go 1 file changed, 28 insertions(+), 0 deletions(-)
To view, visit change 37196. To unsubscribe, visit settings.
Kenny Grant uploaded patch set #6 to this change.
sort: new example: Sorting slices with sort.SliceStable ExampleSliceStable echoes the sort.Slice example, to demonstrate sorting on two fields together preserving order between sorts. Change-Id: I8afc20c0203991bfd57260431eda73913c165355 --- M src/sort/example_test.go 1 file changed, 28 insertions(+), 0 deletions(-)
To view, visit change 37196. To unsubscribe, visit settings.
Kenny Grant posted comments on this change.
Patch set 6:
Patch Set 4: (3 comments)
Thanks, I've uploaded a new version with a different set of names/ages to sort. Re specific points comments below.
(3 comments)
File src/sort/example_test.go:
Patch Set #4, Line 57: {"Colin", 25},
The example is not a good one: Sorting unstable with sort.Slice yields the
I think it's fine to use SliceStable here as that's what the test is for, I've aded a comment to indicate it preserves existing order here (unlike sort.Slice which may or may not).
Stable sorting people by Age where all Ages are distinct is pretty useless:
Yes this was a bad set of ages as sort.Slice would return the same results, I've adjusted the set of names/ages used so that now it consistently returns different results for Slice vs SliceStable - this required a few entries, just Alice and Bob for example won't give different results:
Patch Set #4, Line 62: sort.SliceStable(people, func(i, j int) bool { return people[i].Name < people[j].Name })
Is there a reason to not start a new line after Output: ?
Consistency with other tests in the same file, I don't think this really matters, would rather not edit other tests.
To view, visit change 37196. To unsubscribe, visit settings.
Brad Fitzpatrick posted comments on this change.
Patch set 6:Run-TryBot +1Code-Review +2
Gobot Gobot posted comments on this change.
Patch set 6:
TryBots beginning. Status page: http://farmer.golang.org/try?commit=5ed98381
Gobot Gobot posted comments on this change.
Patch set 6:TryBot-Result +1
TryBots are happy.
Brad Fitzpatrick merged this change.
sort: new example: Sorting slices with sort.SliceStable ExampleSliceStable echoes the sort.Slice example, to demonstrate sorting on two fields together preserving order between sorts. Change-Id: I8afc20c0203991bfd57260431eda73913c165355 Reviewed-on: https://go-review.googlesource.com/37196 Reviewed-by: Brad Fitzpatrick <brad...@golang.org> Run-TryBot: Brad Fitzpatrick <brad...@golang.org> TryBot-Result: Gobot Gobot <go...@golang.org> --- M src/sort/example_test.go 1 file changed, 28 insertions(+), 0 deletions(-)
diff --git a/src/sort/example_test.go b/src/sort/example_test.go
index 980c0d0..89ebe79 100644
--- a/src/sort/example_test.go
+++ b/src/sort/example_test.go
@@ -41,3 +41,31 @@
// Output: By name: [{Alice 55} {Bob 75} {Gopher 7} {Vera 24}]
// By age: [{Gopher 7} {Vera 24} {Alice 55} {Bob 75}]
}
+
+func ExampleSliceStable() {
+
+ people := []struct {
+ Name string
+ Age int
+ }{
+ {"Alice", 25},
+ {"Elizabeth", 75},
+ {"Alice", 75},
+ {"Bob", 75},
+ {"Alice", 75},
+ {"Bob", 25},
+ {"Colin", 25},
+ {"Elizabeth", 25},
+ }
+
+ // Sort by name, preserving original order
+ sort.SliceStable(people, func(i, j int) bool { return people[i].Name < people[j].Name })
+ fmt.Println("By name:", people)
+
+ // Sort by age preserving name order
+ sort.SliceStable(people, func(i, j int) bool { return people[i].Age < people[j].Age })
+ fmt.Println("By age,name:", people)
+
+ // Output: By name: [{Alice 25} {Alice 75} {Alice 75} {Bob 75} {Bob 25} {Colin 25} {Elizabeth 75} {Elizabeth 25}]
+ // By age,name: [{Alice 25} {Bob 25} {Colin 25} {Elizabeth 25} {Alice 75} {Alice 75} {Bob 75} {Elizabeth 75}]
+}
To view, visit change 37196. To unsubscribe, visit settings.