TIP #326: Add -stride Option to lsort
_____________________________________________________________________________
TIP:	326
Title:	Add -stride Option to lsort
Version:	$Revision: 1.5 $
Authors:	Kieran Elby <kieran@dunelm.org.uk>
State:	Final
Type:	Project
Tcl-Version:	8.6
Vote:	Done
Created:	Mon Sep 01 00:00:00 UTC 2008
Keywords:	Tcl, lsort, sorting
Abstract
This TIP adds a new option, -stride, to lsort to request that a list be treated as consisting of repeated groups of elements (as opposed to sublists), and that the the groups be sorted according to a chosen element within each group.
Rationale
Flat name-value pair lists are common in Tcl - consider the output of array get and dict create or the input to foreach.
It is surprising then that there is no command to directly sort such a list by either the name or the value elements, while preserving the name-value mapping.
Doing so currently requires turning a name-value pair list into a list of sublists, using the lsort -index option to sort them, then flattening the list again, which is rather fiddly and inefficient.
While sorting name-value pair lists is no doubt the most common use case, lists containing groups of more than two elements are also reasonably common, and so providing support for groups of any size seems useful and no harder to implement.
The option format follows the Feature Request here: https://sourceforge.net/support/tracker.php?aid=747083
Proposed Change
A new option, -stride, taking one parameter, grpSize will be added to the lsort command.
If -stride is supplied, the list will be treated as consisting of groups of grpSize elements, and the groups will be sorted by either their first element or, if the -index option is used, by the element within each group given by the first index passed to -index (which is then ignored by -index).
Elements always remain in the same position within their group.
The list length must be a multiple of grpSize, which in turn must be at least 2.
Examples
 lsort -stride 2 carrot 10 apple 50 banana 25
returns "apple 50 banana 25 carrot 10"
 lsort -stride 2 -index 1 -integer carrot 10 apple 50 banana 25
returns "carrot 10 banana 25 apple 50"
 lsort -stride 3 -index 0 1 Bob Smith 25 Audi Jane Doe 40 Ford
returns "Jane Doe 40 Ford Bob Smith 25 Audi" (since Smith, which is at index 1 of element 0 of the first group comes after Doe, which is at the same position in the next group of 3.)
Reference Implementation
Available online at https://sourceforge.net/support/tracker.php?aid=2082681
Compatibility
Since this is a new and unambiguous option, and since the distinction between the options and the list to sort is clear, no compatibility problems are expected.
Limitations
Only one element in each group can be used for comparison; it's not possible to compare groups element-by-element.
Further Thoughts
There may be some merit in adding a similar option to lsearch.
The name-value pair case is common enough that an argument could be made for adding -pairname and -pairvalue options as synonyms for -stride 2 -index 0 and -stride 2 -index 1 respectively.
Copyright
This document has been placed in the public domain.
_____________________________________________________________________________
Colophon
TIP AutoGenerator - written by Donal K. Fellows