1#! /usr/bin/env slsh
2
3% This program presents the solution to a problem posed by
4% Tom Christiansen <tchrist@mox.perl.com>.  The problem reads:
5%
6%    Sort an input file that consists of lines like this
7%
8%        var1=23 other=14 ditto=23 fred=2
9%
10%    such that each output line is sorted WRT to the number.  Order
11%    of output lines does not change.  Resolve collisions using the
12%    variable name.   e.g.
13%
14%        fred=2 other=14 ditto=23 var1=23
15%
16%    Lines may be up to several kilobytes in length and contain
17%    zillions of variables.
18%---------------------------------------------------------------------------
19%
20% The solution presented below works by breaking up the line into an
21% array of alternating keywords and values with the keywords as the even
22% elements and the values as the odd.  It is about 30% faster than the
23% python solution.
24
25private variable Keys, Values;
26private define sort_fun (i, j)
27{
28   variable s, a, b;
29
30   s = Values[i] - Values[j];
31   !if (s)
32     return strcmp (Keys[i], Keys[j]);
33   return s;
34}
35
36define slsh_main ()
37{
38   variable line, len, i, vals;
39   foreach line (stdin)
40     {
41	line = strtok (line, " \t\n=");
42	len = length(line)/2;
43	if (len == 0)
44	  continue;
45
46	% Even elements are keys, odd are values
47	Keys = line[[0::2]];
48	vals = line[[1::2]];
49
50	Values = atoi (vals);
51
52	i = array_sort ([0:len-1], &sort_fun);
53
54	% There are different ways of writing the result.  Here is a
55	% fast way that avoids a loop.
56	() = printf ("%s\n", strjoin (Keys[i] + "=" + vals[i], " "));
57     }
58}
59