zsh-users
 help / color / mirror / code / Atom feed
* How to impose a numeric sort on negative numbers?
@ 2020-07-01 17:45 Sebastian Gniazdowski
  2020-07-01 18:02 ` Mikael Magnusson
  2020-07-01 18:48 ` Lawrence Velázquez
  0 siblings, 2 replies; 18+ messages in thread
From: Sebastian Gniazdowski @ 2020-07-01 17:45 UTC (permalink / raw)
  To: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 252 bytes --]

Hi,
arr=( -1A -2b -3B 0 1A 2C 3B )
print -rl ${(on)arr}

Output:
0
1A
-1A
-2b
2C
3B
-3B

So it's not "correct". How to sort from -3 to 2?
-- 
Sebastian Gniazdowski
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zinit
Blog: http://zdharma.org

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 17:45 How to impose a numeric sort on negative numbers? Sebastian Gniazdowski
@ 2020-07-01 18:02 ` Mikael Magnusson
  2020-07-01 18:07   ` Sebastian Gniazdowski
  2020-07-01 19:42   ` Peter Stephenson
  2020-07-01 18:48 ` Lawrence Velázquez
  1 sibling, 2 replies; 18+ messages in thread
From: Mikael Magnusson @ 2020-07-01 18:02 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Zsh Users

On 7/1/20, Sebastian Gniazdowski <sgniazdowski@gmail.com> wrote:
> Hi,
> arr=( -1A -2b -3B 0 1A 2C 3B )
> print -rl ${(on)arr}
>
> Output:
> 0
> 1A
> -1A
> -2b
> 2C
> 3B
> -3B
>
> So it's not "correct". How to sort from -3 to 2?

Works fine here,
% arr=( -1A -2b -3B 0 1A 2C 3B )
% print -rl ${(on)arr}
-1A
-2b
-3B
0
1A
2C
3B


-- 
Mikael Magnusson

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 18:02 ` Mikael Magnusson
@ 2020-07-01 18:07   ` Sebastian Gniazdowski
  2020-07-01 18:12     ` Roman Perepelitsa
  2020-07-03 18:12     ` Lewis Butler
  2020-07-01 19:42   ` Peter Stephenson
  1 sibling, 2 replies; 18+ messages in thread
From: Sebastian Gniazdowski @ 2020-07-01 18:07 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 712 bytes --]

It's weird  that it's different - could you share `allopt' output?

And it's not correct - -1 is before -3, etc.


On Wed, 1 Jul 2020 at 20:03, Mikael Magnusson <mikachu@gmail.com> wrote:

> On 7/1/20, Sebastian Gniazdowski <sgniazdowski@gmail.com> wrote:
> > Hi,
> > arr=( -1A -2b -3B 0 1A 2C 3B )
> > print -rl ${(on)arr}
> >
> > Output:
> > 0
> > 1A
> > -1A
> > -2b
> > 2C
> > 3B
> > -3B
> >
> > So it's not "correct". How to sort from -3 to 2?
>
> Works fine here,
> % arr=( -1A -2b -3B 0 1A 2C 3B )
> % print -rl ${(on)arr}
> -1A
> -2b
> -3B
> 0
> 1A
> 2C
> 3B
>
>
> --
> Mikael Magnusson
>


-- 
Sebastian Gniazdowski
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zinit
Blog: http://zdharma.org

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 18:07   ` Sebastian Gniazdowski
@ 2020-07-01 18:12     ` Roman Perepelitsa
  2020-07-03 18:12     ` Lewis Butler
  1 sibling, 0 replies; 18+ messages in thread
From: Roman Perepelitsa @ 2020-07-01 18:12 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Mikael Magnusson, Zsh Users

On Wed, Jul 1, 2020 at 8:09 PM Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
> It's weird  that it's different - could you share `allopt' output?

It's locale-dependent. Set LC_ALL=C and you'll see the same output as Mikael.

See on the playground:
https://tio.run/##qyrO@J9YVGSroaBr6Kiga5SkoGvspGCgAOQYOSsAmZoEpLkKijLzShR0ixR0dRVUqjXy8zSBGmq5fJzjHX18bJ1xyP//DwA

Roman.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 17:45 How to impose a numeric sort on negative numbers? Sebastian Gniazdowski
  2020-07-01 18:02 ` Mikael Magnusson
@ 2020-07-01 18:48 ` Lawrence Velázquez
  2020-07-06  7:15   ` Sebastian Gniazdowski
  1 sibling, 1 reply; 18+ messages in thread
From: Lawrence Velázquez @ 2020-07-01 18:48 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: zsh-users

> On Jul 1, 2020, at 1:45 PM, Sebastian Gniazdowski
> <sgniazdowski@gmail.com> wrote:
> 
> Hi,
> arr=( -1A -2b -3B 0 1A 2C 3B )
> print -rl ${(on)arr}
> 
> Output:
> 0
> 1A
> -1A
> -2b
> 2C
> 3B
> -3B
> 
> So it's not "correct". How to sort from -3 to 2?

arguably cheating, and not robust since no one has any idea how
clean your input is, but YOLO so whatever ;)

% arr=(-1A -2b -3B 0 1A 2C 3B)
% arr_sorted=(${(MOn)arr:#-*} ${(n)arr:#-*})
% print -rl $arr_sorted
-3B
-2b
-1A
0
1A
2C
3B


--
vq

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 18:02 ` Mikael Magnusson
  2020-07-01 18:07   ` Sebastian Gniazdowski
@ 2020-07-01 19:42   ` Peter Stephenson
  2020-07-02 11:36     ` Daniel Shahaf
  1 sibling, 1 reply; 18+ messages in thread
From: Peter Stephenson @ 2020-07-01 19:42 UTC (permalink / raw)
  To: zsh-users

On Wed, 2020-07-01 at 20:02 +0200, Mikael Magnusson wrote:
> Works fine here,
> % arr=( -1A -2b -3B 0 1A 2C 3B )
> % print -rl ${(on)arr}
> -1A
> -2b
> -3B
> 0
> 1A
> 2C
> 3B

If you look a bit more closely I think you'll see there's a problem even
there...

We could do something like the following.  Feel free to suggest a more
comprehensive test.

pws

diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 69cb0b08a..8db97ab5d 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1097,6 +1097,11 @@ are sorted before those with fewer or none.  Hence the array `tt(foo1 foo02
 foo2 foo3 foo20 foo23)' is sorted into the order shown.
 May be combined with `tt(i)' or `tt(O)'.
 )
+item(tt(DASH()))(
+As tt(n), but a leading minus sign indicates a negative decimal
+integer.  A solo `tt(DASH())' not followed by an integer does
+not trigger numeric sorting.
+)
 item(tt(o))(
 Sort the resulting words in ascending order; if this appears on its
 own the sorting is lexical and case-sensitive (unless the locale
diff --git a/Src/sort.c b/Src/sort.c
index 8faf9349c..26949ad9c 100644
--- a/Src/sort.c
+++ b/Src/sort.c
@@ -135,12 +135,23 @@ eltpcmp(const void *a, const void *b)
 #endif
 
     if (sortnumeric) {
+	int mul = 0;
 	for (; *as == *bs && *as; as++, bs++);
 #ifndef HAVE_STRCOLL
 	cmp = (int)STOUC(*as) - (int)STOUC(*bs);
 #endif
-	if (idigit(*as) || idigit(*bs)) {
+	if (sortnumeric < 0) {
+	    if (*as == '-' && idigit(as[1]) && idigit(*bs)) {
+		cmp = -1;
+		mul = 1;
+	    } else if (*bs == '-' && idigit(bs[1]) && idigit(*as)) {
+		cmp = 1;
+		mul = 1;
+	    }
+	}
+	if (!mul && (idigit(*as) || idigit(*bs))) {
 	    for (; as > ao && idigit(as[-1]); as--, bs--);
+	    mul = (sortnumeric < 0 && as > ao && as[-1] == '-') ? -1 : 1;
 	    if (idigit(*as) && idigit(*bs)) {
 		while (*as == '0')
 		    as++;
@@ -148,13 +159,13 @@ eltpcmp(const void *a, const void *b)
 		    bs++;
 		for (; idigit(*as) && *as == *bs; as++, bs++);
 		if (idigit(*as) || idigit(*bs)) {
-		    cmp = (int)STOUC(*as) - (int)STOUC(*bs);
+		    cmp = mul * ((int)STOUC(*as) - (int)STOUC(*bs));
 		    while (idigit(*as) && idigit(*bs))
 			as++, bs++;
 		    if (idigit(*as) && !idigit(*bs))
-			return sortdir;
+			return mul * sortdir;
 		    if (idigit(*bs) && !idigit(*as))
-			return -sortdir;
+			return -mul * sortdir;
 		}
 	    }
 	}
@@ -195,7 +206,8 @@ zstrcmp(const char *as, const char *bs, int sortflags)
 
     sortdir = 1;
     sortnobslash = (sortflags & SORTIT_IGNORING_BACKSLASHES) ? 1 : 0;
-    sortnumeric = (sortflags & SORTIT_NUMERICALLY) ? 1 : 0;
+    sortnumeric = (sortflags & SORTIT_NUMERICALLY_SIGNED) ? -1 :
+	(sortflags & SORTIT_NUMERICALLY) ? 1 : 0;
 
     ret = eltpcmp(&aeptr, &beptr);
 
@@ -389,7 +401,8 @@ strmetasort(char **array, int sortwhat, int *unmetalenp)
     oldsortnumeric = sortnumeric;
 
     sortdir = (sortwhat & SORTIT_BACKWARDS) ? -1 : 1;
-    sortnumeric = (sortwhat & SORTIT_NUMERICALLY) ? 1 : 0;
+    sortnumeric = (sortwhat & SORTIT_NUMERICALLY_SIGNED) ? -1 :
+	(sortwhat & SORTIT_NUMERICALLY) ? 1 : 0;
 
     qsort(sortptrarr, nsort, sizeof(SortElt), eltpcmp);
 
diff --git a/Src/subst.c b/Src/subst.c
index 90b5fc121..d7ede9cb1 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1979,6 +1979,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
 		case 'n':
 		    sortit |= SORTIT_NUMERICALLY;
 		    break;
+		case '-':
+		case Dash:
+		    sortit |= SORTIT_NUMERICALLY_SIGNED;
+		    break;
 		case 'a':
 		    sortit |= SORTIT_SOMEHOW;
 		    indord = 1;
diff --git a/Src/zsh.h b/Src/zsh.h
index 1f2d774a1..8c156bf77 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2996,17 +2996,18 @@ enum {
     SORTIT_ANYOLDHOW = 0,	/* Defaults */
     SORTIT_IGNORING_CASE = 1,
     SORTIT_NUMERICALLY = 2,
-    SORTIT_BACKWARDS = 4,
+    SORTIT_NUMERICALLY_SIGNED = 4,
+    SORTIT_BACKWARDS = 8,
     /*
      * Ignore backslashes that quote another character---which may
      * be another backslash; the second backslash is active.
      */
-    SORTIT_IGNORING_BACKSLASHES = 8,
+    SORTIT_IGNORING_BACKSLASHES = 16,
     /*
      * Ignored by strmetasort(); used by paramsubst() to indicate
      * there is some sorting to do.
      */
-    SORTIT_SOMEHOW = 16,
+    SORTIT_SOMEHOW = 32,
 };
 
 /*
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index e51c955ee..ac99ff0e3 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -1398,6 +1398,13 @@
 >a6 a17 a117 b6 b17 b117
 >b117 b17 b6 a117 a17 a6
 
+  foo=(a-6 a117 a-17 a-34 b6 b-117 b17 b-2)
+  print ${(-)foo}
+  print ${(O-)foo}
+0:Numeric sorting of signed integers
+>a-34 a-17 a-6 a117 b-117 b-2 b6 b17
+>b17 b6 b-2 b-117 a117 a-6 a-17 a-34
+
   x=sprodj
   x[-10]=scrumf
   print $x


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 19:42   ` Peter Stephenson
@ 2020-07-02 11:36     ` Daniel Shahaf
  2020-07-02 12:00       ` Peter Stephenson
  2020-07-02 15:46       ` How to impose a numeric sort on negative numbers? Bart Schaefer
  0 siblings, 2 replies; 18+ messages in thread
From: Daniel Shahaf @ 2020-07-02 11:36 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-users

Peter Stephenson wrote on Wed, 01 Jul 2020 20:42 +0100:
> +++ b/Doc/Zsh/expn.yo
> @@ -1097,6 +1097,11 @@ are sorted before those with fewer or none.  Hence the array `tt(foo1 foo02
>  foo2 foo3 foo20 foo23)' is sorted into the order shown.
>  May be combined with `tt(i)' or `tt(O)'.
>  )
> +item(tt(DASH()))(
> +As tt(n), but a leading minus sign indicates a negative decimal
> +integer.  A solo `tt(DASH())' not followed by an integer does
> +not trigger numeric sorting.
> +)

In the texinfo build DASH() will emit _two_ hyphens, which would be
incorrect in this context.  I think both instances of DASH() should be
changed to use a literal minus sign.

The macro is defined as «DEFINEMACRO(DASH)(0)(ifztexi(--)ifnztexi(-))».

Cheers,

Daniel

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-02 11:36     ` Daniel Shahaf
@ 2020-07-02 12:00       ` Peter Stephenson
  2020-07-03 16:21         ` Hyphens, minuses, and dashes (was: Re: How to impose a numeric sort on negative numbers?) Daniel Shahaf
  2020-07-02 15:46       ` How to impose a numeric sort on negative numbers? Bart Schaefer
  1 sibling, 1 reply; 18+ messages in thread
From: Peter Stephenson @ 2020-07-02 12:00 UTC (permalink / raw)
  To: zsh-users

> On 02 July 2020 at 12:36 Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> Peter Stephenson wrote on Wed, 01 Jul 2020 20:42 +0100:
> > +++ b/Doc/Zsh/expn.yo
> > @@ -1097,6 +1097,11 @@ are sorted before those with fewer or none.  Hence the array `tt(foo1 foo02
> >  foo2 foo3 foo20 foo23)' is sorted into the order shown.
> >  May be combined with `tt(i)' or `tt(O)'.
> >  )
> > +item(tt(DASH()))(
> > +As tt(n), but a leading minus sign indicates a negative decimal
> > +integer.  A solo `tt(DASH())' not followed by an integer does
> > +not trigger numeric sorting.
> > +)
> 
> In the texinfo build DASH() will emit _two_ hyphens, which would be
> incorrect in this context.  I think both instances of DASH() should be
> changed to use a literal minus sign.
> 
> The macro is defined as «DEFINEMACRO(DASH)(0)(ifztexi(--)ifnztexi(-))».

Heh.  This stuff's complicated.  The two dashes correspond to an en-dash
in TeX.  If you look where DASH() is actually used in the text it's
in places where it gets combined with another dash --- which would
make an em-dash in TeX.  Info is aware of this, so turns -- back into
a single minus.  So compare the output from a use of DASH()- (not
a typo, there's an extra hyphen)...

Info file:

     of the backreferences fail to match -- which happens if they are in

- a visible two dashes, the usual convention to show it's a dash, not a hyphen

.texi file:

    backreferences fail to match --- which happens if they are in an alternate

- three dashes, converted by TeX into an em-dash in print.

So it's sort of doing the right thing at least from the point of what's visible
in text.

However(!), what we really want here is indeed an ASCII hyphen, because this
is what your're typing.  (It's not even actually a minus sign because this
is an input code, not a mathematical expression.  For what it's worth, which
is very little, this would be different in TeX, $-$, but no other format I
know of really cares.)

I have a vague memory we got into problems with such things in YODL once,
which is why I used the macro.  But looking at the current doc source doesn't
suggest any trace of it, so I'll abandon that.  There have been many improvements
in YODL since then.

pws

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-02 11:36     ` Daniel Shahaf
  2020-07-02 12:00       ` Peter Stephenson
@ 2020-07-02 15:46       ` Bart Schaefer
  2020-07-03 20:08         ` Peter Stephenson
  1 sibling, 1 reply; 18+ messages in thread
From: Bart Schaefer @ 2020-07-02 15:46 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Peter Stephenson, Zsh Users

(Dangit, I'm not getting Peter's mail again)

On Thu, Jul 2, 2020 at 4:38 AM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> Peter Stephenson wrote on Wed, 01 Jul 2020 20:42 +0100:
> > +++ b/Doc/Zsh/expn.yo
> > @@ -1097,6 +1097,11 @@ are sorted before those with fewer or none.  Hence the array `tt(foo1 foo02
> >  foo2 foo3 foo20 foo23)' is sorted into the order shown.
> >  May be combined with `tt(i)' or `tt(O)'.
> >  )
> > +item(tt(DASH()))(
> > +As tt(n), but a leading minus sign indicates a negative decimal
> > +integer.  A solo `tt(DASH())' not followed by an integer does
> > +not trigger numeric sorting.
> > +)

It might be possible to change this.  For numeric sort, the function
eltpcmp() in sort.c ignores everything other than digits that compares
the same in any pair of the strings.  It could recognize a leading
hyphen as special.

The questionable thing is what to do about embedded hyphens.  If I'm
asked to sort (1-5 1-3, 1-4 1-2) numerically, what does the hyphen
mean?  Right now it's just ignored.  Reverse the order of the sort
every time we encounter a hyphen?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Hyphens, minuses, and dashes (was: Re: How to impose a numeric sort on negative numbers?)
  2020-07-02 12:00       ` Peter Stephenson
@ 2020-07-03 16:21         ` Daniel Shahaf
  0 siblings, 0 replies; 18+ messages in thread
From: Daniel Shahaf @ 2020-07-03 16:21 UTC (permalink / raw)
  To: zsh-users

Peter Stephenson wrote on Thu, 02 Jul 2020 12:00 +00:00:
> So it's sort of doing the right thing at least from the point of what's visible
> in text.
> 
> However(!), what we really want here is indeed an ASCII hyphen, because this
> is what your're typing.

To be clear, I never proposed to change the definition of DASH(); I only said
the new text shouldn't use that macro.  We seem to be in agreement on that.

Thanks for the background on TeX's handling of hyphens.  (I was already
familiar with most of those details, actually, though not with info(1)'s
handling of runs of hyphens.)

> (It's not even actually a minus sign because this is an input code,
> not a mathematical expression. For what it's worth, which is very
> little, this would be different in TeX, $-$, but no other format I
> know of really cares.)

TeX is not the only format that distinguishes hyphen and minus; Unicode
does, too.  (There's U+2010 HYPHEN, U+2212 MINUS SIGN, and even U+00AD
SOFT HYPHEN.)

> I have a vague memory we got into problems with such things in YODL
> once, which is why I used the macro.  But looking at the current doc
> source doesn't suggest any trace of it, so I'll abandon that.  There
> have been many improvements in YODL since then.

Hmm.  This reminds me: in the HTML FAQ emdash() renders as «"---"»,
whereas in the HTML manual «DASH()-» is rendered as "—".

Looking at the respective Makefiles, I suspect this might be because the
FAQ is built by yodl2html(1), whereas the manual is built by yodl +
texi2any(1) [= $(TEXI2HTML)].

> pws

Cheers,

Daniel

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 18:07   ` Sebastian Gniazdowski
  2020-07-01 18:12     ` Roman Perepelitsa
@ 2020-07-03 18:12     ` Lewis Butler
  2020-07-03 18:35       ` Bart Schaefer
  1 sibling, 1 reply; 18+ messages in thread
From: Lewis Butler @ 2020-07-03 18:12 UTC (permalink / raw)
  To: Zsh Users



> On 01 Jul 2020, at 12:07, Sebastian Gniazdowski <sgniazdowski@gmail.com> wrote:
> 
> On Wed, 1 Jul 2020 at 20:03, Mikael Magnusson <mikachu@gmail.com> wrote:
> 
>> On 7/1/20, Sebastian Gniazdowski <sgniazdowski@gmail.com> wrote:
>>> Hi,
>>> arr=( -1A -2b -3B 0 1A 2C 3B )
>>> print -rl ${(on)arr}
>>> 
>>> Output:
>>> 0
>>> 1A
>>> -1A
>>> -2b
>>> 2C
>>> 3B
>>> -3B
>>> 
>>> So it's not "correct". How to sort from -3 to 2?
>> 
>> Works fine here,
>> % arr=( -1A -2b -3B 0 1A 2C 3B )
>> % print -rl ${(on)arr}
>> -1A
>> -2b
>> -3B
>> 0
>> 1A
>> 2C
>> 3B

> It's weird  that it's different - could you share `allopt' output?
> 
> And it's not correct - -1 is before -3, etc.

arr=( -1A -2b -3B 0 1A 2C 3B ); print -l ${(on)arr} | sort -h

Or is that cheating?

-- 
ɹןʇnqן
<mailto:lbutler@covisp.net>
tel:+1.303.219.0564




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-03 18:12     ` Lewis Butler
@ 2020-07-03 18:35       ` Bart Schaefer
  0 siblings, 0 replies; 18+ messages in thread
From: Bart Schaefer @ 2020-07-03 18:35 UTC (permalink / raw)
  To: Lewis Butler; +Cc: Zsh Users

On Fri, Jul 3, 2020 at 11:13 AM Lewis Butler <lbutler@covisp.net> wrote:
>
> arr=( -1A -2b -3B 0 1A 2C 3B ); print -l ${(on)arr} | sort -h
>
> Or is that cheating?

Well, it's sort of cheating, but it's not correct either, because "1G"
would sort after "1K".  I think you want "sort -n" rather than -h.
And if you're piping to sort anyway, there's no reason to use (on)
first.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-02 15:46       ` How to impose a numeric sort on negative numbers? Bart Schaefer
@ 2020-07-03 20:08         ` Peter Stephenson
  2020-07-03 20:15           ` Bart Schaefer
  2020-07-03 22:23           ` Daniel Shahaf
  0 siblings, 2 replies; 18+ messages in thread
From: Peter Stephenson @ 2020-07-03 20:08 UTC (permalink / raw)
  To: zsh-users

On Thu, 2020-07-02 at 08:46 -0700, Bart Schaefer wrote:
> Peter Stephenson wrote on Wed, 01 Jul 2020 20:42 +0100:
> > > +++ b/Doc/Zsh/expn.yo
> > > @@ -1097,6 +1097,11 @@ are sorted before those with fewer or none.  Hence the array `tt(foo1 foo02
> > >  foo2 foo3 foo20 foo23)' is sorted into the order shown.
> > >  May be combined with `tt(i)' or `tt(O)'.
> > >  )
> > > +item(tt(DASH()))(
> > > +As tt(n), but a leading minus sign indicates a negative decimal
> > > +integer.  A solo `tt(DASH())' not followed by an integer does
> > > +not trigger numeric sorting.
> > > +)
> 
> It might be possible to change this.  For numeric sort, the function
> eltpcmp() in sort.c ignores everything other than digits that compares
> the same in any pair of the strings.  It could recognize a leading
> hyphen as special.

(I've committed it with DASH() turned into -.)

The doc was just to record the fact that I didn't treat a "-" as "-0",
just as a character "-".  That was a deliberate choice --- I'm
assuming the usual case of a numeric sort will have at least one
decimal digit in the part to be sorted and anything else is
just a hyphen (and definitely not a dash).

pws



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-03 20:08         ` Peter Stephenson
@ 2020-07-03 20:15           ` Bart Schaefer
  2020-07-03 22:23           ` Daniel Shahaf
  1 sibling, 0 replies; 18+ messages in thread
From: Bart Schaefer @ 2020-07-03 20:15 UTC (permalink / raw)
  To: zsh-users

On Fri, 3 Jul 2020, Peter Stephenson wrote:

> The doc was just to record the fact that I didn't treat a "-" as "-0"

Yeah, you pretty much did exactly what I was suggesting, except that I 
didn't see the patch because gmail is rejecting mailing list forwards from 
ntlworld.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-03 20:08         ` Peter Stephenson
  2020-07-03 20:15           ` Bart Schaefer
@ 2020-07-03 22:23           ` Daniel Shahaf
  2020-07-07 16:14             ` Daniel Shahaf
  1 sibling, 1 reply; 18+ messages in thread
From: Daniel Shahaf @ 2020-07-03 22:23 UTC (permalink / raw)
  To: zsh-users

Peter Stephenson wrote on Fri, 03 Jul 2020 20:08 +00:00:
> On Thu, 2020-07-02 at 08:46 -0700, Bart Schaefer wrote:
> > Peter Stephenson wrote on Wed, 01 Jul 2020 20:42 +0100:
> > > > +++ b/Doc/Zsh/expn.yo
> > > > @@ -1097,6 +1097,11 @@ are sorted before those with fewer or none.  Hence the array `tt(foo1 foo02
> > > >  foo2 foo3 foo20 foo23)' is sorted into the order shown.
> > > >  May be combined with `tt(i)' or `tt(O)'.
> > > >  )
> > > > +item(tt(DASH()))(
> > > > +As tt(n), but a leading minus sign indicates a negative decimal
> > > > +integer.  A solo `tt(DASH())' not followed by an integer does
> > > > +not trigger numeric sorting.
> > > > +)
> > 
> > It might be possible to change this.  For numeric sort, the function
> > eltpcmp() in sort.c ignores everything other than digits that compares
> > the same in any pair of the strings.  It could recognize a leading
> > hyphen as special.
> 
> (I've committed it with DASH() turned into -.)
> 

(Turns out there were five instances of tt(DASH()), not two as I implied
in my review, so I've gone ahead and changed those as well.)

> The doc was just to record the fact that I didn't treat a "-" as "-0",
> just as a character "-".  That was a deliberate choice --- I'm
> assuming the usual case of a numeric sort will have at least one
> decimal digit in the part to be sorted and anything else is
> just a hyphen (and definitely not a dash).

FWIW, I thought at first reading that that second sentence referred to
the `tt(-)' in the parameter expansion flags, not to the one in the
input data.  I'd never have expected "-" or "-foo" to be considered an
integer in the first place, just like "" and "foo" aren't considered integers.

Incidentally, should "+42" be sorted as an integer?  Right now it isn't.

Cheers,

Daniel

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-01 18:48 ` Lawrence Velázquez
@ 2020-07-06  7:15   ` Sebastian Gniazdowski
  0 siblings, 0 replies; 18+ messages in thread
From: Sebastian Gniazdowski @ 2020-07-06  7:15 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 473 bytes --]

On Wed, 1 Jul 2020 at 20:48, Lawrence Velázquez <vq@larryv.me> wrote:

> arguably cheating, and not robust since no one has any idea how
> clean your input is, but YOLO so whatever ;)
>
> % arr=(-1A -2b -3B 0 1A 2C 3B)
> % arr_sorted=(${(MOn)arr:#-*} ${(n)arr:#-*})
> % print -rl $arr_sorted
> -3B
> -2b
>

That's a good solution, thanks!

-- 
Sebastian Gniazdowski
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zinit
Blog: http://zdharma.org

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-03 22:23           ` Daniel Shahaf
@ 2020-07-07 16:14             ` Daniel Shahaf
  2020-07-07 16:18               ` Daniel Shahaf
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel Shahaf @ 2020-07-07 16:14 UTC (permalink / raw)
  To: zsh-users

Daniel Shahaf wrote on Fri, 03 Jul 2020 22:23 +0000:
> > The doc was just to record the fact that I didn't treat a "-" as "-0",
> > just as a character "-".  That was a deliberate choice --- I'm
> > assuming the usual case of a numeric sort will have at least one
> > decimal digit in the part to be sorted and anything else is
> > just a hyphen (and definitely not a dash).  
> 
> FWIW, I thought at first reading that that second sentence referred to
> the `tt(-)' in the parameter expansion flags, not to the one in the
> input data.  I'd never have expected "-" or "-foo" to be considered an
> integer in the first place, just like "" and "foo" aren't considered integers.
> 
> Incidentally, should "+42" be sorted as an integer?  Right now it isn't.

The following patch addresses the first issue and documents "+42" as a
possible future extension.

Cheers,

Daniel


diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 41ad967b2..21ecf9d6e 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1092,15 +1092,18 @@ Convert all letters in the result to lower case.
 item(tt(n))(
 Sort decimal integers numerically; if the first differing
 characters of two test strings are not digits, sorting
-is lexical.   Integers with more initial zeroes
-are sorted before those with fewer or none.  Hence the array `tt(foo1 foo02
+is lexical.  `tt(+)' and `tt(-)' are not treated specially; they are treated as
+any other non-digit.  Integers with more initial zeroes
+are sorted before those with fewer or none.  Hence the array `tt(foo+24 foo1 foo02
 foo2 foo3 foo20 foo23)' is sorted into the order shown.
 May be combined with `tt(i)' or `tt(O)'.
 )
 item(tt(-))(
 As tt(n), but a leading minus sign indicates a negative decimal
-integer.  A `tt(-)' not followed by an integer does not trigger
+integer.  A leading minus sign not followed by an integer does not trigger
 numeric sorting.
+Note that `tt(+)' signs are not handled specially (this may change in the
+future).
 )
 item(tt(o))(
 Sort the resulting words in ascending order; if this appears on its

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: How to impose a numeric sort on negative numbers?
  2020-07-07 16:14             ` Daniel Shahaf
@ 2020-07-07 16:18               ` Daniel Shahaf
  0 siblings, 0 replies; 18+ messages in thread
From: Daniel Shahaf @ 2020-07-07 16:18 UTC (permalink / raw)
  To: zsh-users

Daniel Shahaf wrote on Tue, 07 Jul 2020 16:14 +0000:
> Daniel Shahaf wrote on Fri, 03 Jul 2020 22:23 +0000:
> > > The doc was just to record the fact that I didn't treat a "-" as "-0",
> > > just as a character "-".  That was a deliberate choice --- I'm
> > > assuming the usual case of a numeric sort will have at least one
> > > decimal digit in the part to be sorted and anything else is
> > > just a hyphen (and definitely not a dash).    
> > 
> > FWIW, I thought at first reading that that second sentence referred to
> > the `tt(-)' in the parameter expansion flags, not to the one in the
> > input data.  I'd never have expected "-" or "-foo" to be considered an
> > integer in the first place, just like "" and "foo" aren't considered integers.
> > 
> > Incidentally, should "+42" be sorted as an integer?  Right now it isn't.  
> 
> The following patch addresses the first issue and documents "+42" as a
> possible future extension.
> 
> diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
> index 41ad967b2..21ecf9d6e 100644
> --- a/Doc/Zsh/expn.yo
> +++ b/Doc/Zsh/expn.yo
> @@ -1092,15 +1092,18 @@ Convert all letters in the result to lower case.

Equivalent wdiff for review:

diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 41ad967b2..21ecf9d6e 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1092,15 +1092,18 @@ Convert all letters in the result to lower case.
item(tt(n))(
Sort decimal integers numerically; if the first differing
characters of two test strings are not digits, sorting
is lexical.  {+`tt(+)' and `tt(-)' are not treated specially; they are treated as+}
{+any other non-digit.+}  Integers with more initial zeroes
are sorted before those with fewer or none.  Hence the array [-`tt(foo1-]{+`tt(foo+24 foo1+} foo02
foo2 foo3 foo20 foo23)' is sorted into the order shown.
May be combined with `tt(i)' or `tt(O)'.
)
item(tt(-))(
As tt(n), but a leading minus sign indicates a negative decimal
integer.  A [-`tt(-)'-]{+leading minus sign+} not followed by an integer does not trigger
numeric sorting.
{+Note that `tt(+)' signs are not handled specially (this may change in the+}
{+future).+}
)
item(tt(o))(
Sort the resulting words in ascending order; if this appears on its

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2020-07-07 16:19 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-01 17:45 How to impose a numeric sort on negative numbers? Sebastian Gniazdowski
2020-07-01 18:02 ` Mikael Magnusson
2020-07-01 18:07   ` Sebastian Gniazdowski
2020-07-01 18:12     ` Roman Perepelitsa
2020-07-03 18:12     ` Lewis Butler
2020-07-03 18:35       ` Bart Schaefer
2020-07-01 19:42   ` Peter Stephenson
2020-07-02 11:36     ` Daniel Shahaf
2020-07-02 12:00       ` Peter Stephenson
2020-07-03 16:21         ` Hyphens, minuses, and dashes (was: Re: How to impose a numeric sort on negative numbers?) Daniel Shahaf
2020-07-02 15:46       ` How to impose a numeric sort on negative numbers? Bart Schaefer
2020-07-03 20:08         ` Peter Stephenson
2020-07-03 20:15           ` Bart Schaefer
2020-07-03 22:23           ` Daniel Shahaf
2020-07-07 16:14             ` Daniel Shahaf
2020-07-07 16:18               ` Daniel Shahaf
2020-07-01 18:48 ` Lawrence Velázquez
2020-07-06  7:15   ` Sebastian Gniazdowski

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).