Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #18714 > unrolled thread

sort array

Started by"Tony" <tony.johansson@inport.com>
First post2013-03-04 18:33 +0100
Last post2013-03-05 21:10 +0000
Articles 7 — 6 participants

Back to article view | Back to comp.lang.javascript


Contents

  sort array "Tony" <tony.johansson@inport.com> - 2013-03-04 18:33 +0100
    Re: sort array "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2013-03-04 19:19 +0100
    Re: sort array "J.R." <groups_jr-1@yahoo.com.br> - 2013-03-05 00:07 -0300
      Re: sort array Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-03-05 17:51 +0100
        Re: sort array "Joao Rodrigues (J.R.)" <groups_jr-1@yahoo.com.br> - 2013-03-09 02:33 -0300
          Re: sort array Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-03-09 13:01 +0100
    Re: sort array Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-03-05 21:10 +0000

#18714 — sort array

From"Tony" <tony.johansson@inport.com>
Date2013-03-04 18:33 +0100
Subjectsort array
Message-ID<kh2lrk$ena$1@dont-email.me>
I have an array called tempArray that consist of these fields
VesselID, ETATime, Gotref, Point

When I want to sort on VesselID I use which works good
tempArray.sort(function (a, b)
{
        return a.VesselID - b.VesselID
})


Now I still want to sort on VesselID but within VesselID I also want to sort 
on ETATime
ETATime which is of format YYYY/MM/DD hh:mm:ss

How can I do that ?

//Tony

[toc] | [next] | [standalone]


#18715

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2013-03-04 19:19 +0100
Message-ID<XnsA179C49015389eejj99@194.109.133.133>
In reply to#18714
Tony wrote on 04 mrt 2013 in comp.lang.javascript:

> I have an array called tempArray that consist of these fields
> VesselID, ETATime, Gotref, Point
> 
> When I want to sort on VesselID I use which works good
> tempArray.sort(function (a, b)
> {
    var temp = a.VesselID - b.VesselID;
    if temp = 0 then temp = a.ETATime - b.ETATime;
    return temp;
>})

[not tested]

or a miriad of other ways

> 
> Now I still want to sort on VesselID but within VesselID I also want
> to sort on ETATime
> ETATime which is of format YYYY/MM/DD hh:mm:ss
> 
> How can I do that ?
> 
> //Tony
> 
> 
> 



-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#18717

From"J.R." <groups_jr-1@yahoo.com.br>
Date2013-03-05 00:07 -0300
Message-ID<kh3ngq$jn4$1@speranza.aioe.org>
In reply to#18714
On 04/03/2013 14:33, Tony wrote:
> I have an array called tempArray that consist of these fields
> VesselID, ETATime, Gotref, Point
>
> When I want to sort on VesselID I use which works good
> tempArray.sort(function (a, b)
> {
>         return a.VesselID - b.VesselID
> })
>
>
> Now I still want to sort on VesselID but within VesselID I also want to
> sort on ETATime
> ETATime which is of format YYYY/MM/DD hh:mm:ss
>
> How can I do that ?

Assuming that the ETATime string will always be in that format 
(yyyy/mm/dd hh:mm:ss), then we might use a function like this:

function sortETA(a, b) {
   // a and b are strings representing a date-time
   // of format yyyy/mm/dd hh:mm:ss
   var e1, e2, re = /[/:\s]/g;
   e1 = a.replace(re, ''); // converts to yyyymmddhhmmss
   e2 = b.replace(re, ''); // idem
   if (e1 === e2) { return 0; }
   return (e1 < e2) ? -1 : 1;
}

var arr = ['2013/03/06 10:23:01', '2013/03/05 23:59:01',
            '2013/03/06 00:00:59', '2013/03/05 22:15:00'];

arr.sort(sortETA);


However, you'd be better off testing for the expected ETA string format 
passed as the arguments to the sortETA(), using regular expressions: 
test whether you have the expected number of digits, spaces etc. for the 
date and time parts of the string)

-- 
Joao Rodrigues (J.R.)

[toc] | [prev] | [next] | [standalone]


#18723

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-03-05 17:51 +0100
Message-ID<7839584.47tHrR2Uyp@PointedEars.de>
In reply to#18717
J.R. wrote:

> On 04/03/2013 14:33, Tony wrote:
>> I have an array called tempArray that consist of these fields
>> VesselID, ETATime, Gotref, Point
>>
>> When I want to sort on VesselID I use which works good
>> tempArray.sort(function (a, b)
>> {
>>         return a.VesselID - b.VesselID
>> })
>>
>>
>> Now I still want to sort on VesselID but within VesselID I also want to
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> sort on ETATime
   ^^^^^^^^^^^^^^^
>> ETATime which is of format YYYY/MM/DD hh:mm:ss
>>
>> How can I do that ?
> 
> Assuming that the ETATime string will always be in that format
> (yyyy/mm/dd hh:mm:ss), then we might use a function like this:
> 
> function sortETA(a, b) {
>    // a and b are strings representing a date-time
>    // of format yyyy/mm/dd hh:mm:ss
>    var e1, e2, re = /[/:\s]/g;
>    e1 = a.replace(re, ''); // converts to yyyymmddhhmmss
>    e2 = b.replace(re, ''); // idem
>    if (e1 === e2) { return 0; }
>    return (e1 < e2) ? -1 : 1;
> }
> 
> var arr = ['2013/03/06 10:23:01', '2013/03/05 23:59:01',
>             '2013/03/06 00:00:59', '2013/03/05 22:15:00'];
> 
> arr.sort(sortETA);

Or you could make Date objects out of the string values (see previous 
discussions) and sort those.  For example, if you can be sure that the 
implementation is one of ECMAScript Edition 5 or 5.1, you could replace “/” 
with “-” and “ ” with “T” and pass that to the Date constructor, because
the result is the simplified ISO 8601 time format supported by those 
implementations (ES 5.1, §15.9.1.5), and Date values of the same time zone 
sort easily because converting them to Number yields their time value (see 
also those discussions).

> However, you'd be better off testing for the expected ETA string format
> passed as the arguments to the sortETA(), using regular expressions:
> test whether you have the expected number of digits, spaces etc. for the
> date and time parts of the string)

Or you could get just the minimum clue and learn that this particular date 
format (with leading zeroes and fixed length) can be sorted as a string, 
i.e. *without* such an awfully *inefficient* user-defined comparator:

  var arr = ['2013/03/06 10:23:01', '2013/03/05 23:59:01',
             '2013/03/06 00:00:59', '2013/03/05 22:15:00'];
  arr.sort();

That said, due to your careless reading your answer does not address the 
question at all; which is basically how to sort using two sort keys (which 
should rather be a topic for “Programming 101”).  The simplest answer to 
that is, for example (for ascending order in both cases):

  tempArray.sort(function (a, b) {
    /* first key */
    var ax = a.x;
    var bx = b.x;

    if (ax < bx)
    {
      return -1;
    }

    if (ax > bx)
    {
      return 1;
    }

    /* else ax == bx */

    /* second key */
    var ay = a.y;
    var by = b.y;

    if (ay < by)
    {
      return -1;
    }

    if (ay > by)
    {
      return 1;
    }

    return 0;
  });

In this case it can be slightly optimized to

  tempArray.sort(function (a, b) {
    /* first key */
    var ax = a.x;
    var bx = b.x;

    /*
     * assuming ax and bx are Number values or convertible;
     * alternative:
     *
     *   var diff = ax - bx;
     *   if (diff) { return diff; }
     */
    if (ax != bx)
    {
      return ax - bx;
    }

    /* else ax == bx */

    /* second key, non-numeric */
    var ay = a.y;
    var by = b.y;

    if (ay < by)
    {
      return -1;
    }

    if (ay > by)
    {
      return 1;
    }

    return 0;
  });

Of course, thanks to the bracket property accessor and loops this can be 
generalized, which has been done before.  But apparently “Tony” could not 
care less and is continuing to fire off all his questions at this newsgroup 
in spite of documentation and previous discussions.
 
-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#18781

From"Joao Rodrigues (J.R.)" <groups_jr-1@yahoo.com.br>
Date2013-03-09 02:33 -0300
Message-ID<khehj7$2hm$1@speranza.aioe.org>
In reply to#18723
On 05/03/2013 13:51, Thomas 'PointedEars' Lahn wrote:

> Or you could make Date objects out of the string values (see
> previous discussions) and sort those.  For example, if you can be
> sure that the implementation is one of ECMAScript Edition 5 or 5.1,
> you could replace “/” with “-” and “ ” with “T” and pass that to the
> Date constructor, because the result is the simplified ISO 8601 time
> format supported by those implementations (ES 5.1, §15.9.1.5), and
> Date values of the same time zone sort easily because converting them
> to Number yields their time value (see also those discussions).
>

Theoretical. Remember the code will run in the client-side, while the
page could be accessed by users from different time zones, or by users 
that have their computers' clocks set to different time zones (which is 
common in maritime companies). Red herring and Argumentum verbosium.

>> However, you'd be better off testing for the expected ETA string
>> format passed as the arguments to the sortETA(), using regular
>> expressions: test whether you have the expected number of digits,
>> spaces etc. for the date and time parts of the string)
>
> Or you could get just the minimum clue and learn that this particular
> date format (with leading zeroes and fixed length) can be sorted as a
> string, i.e. *without* such an awfully *inefficient* user-defined
> comparator:
>
> var arr = ['2013/03/06 10:23:01', '2013/03/05 23:59:01', '2013/03/06
> 00:00:59', '2013/03/05 22:15:00']; arr.sort();
>

This is known as /defensive programming/. As to the "awfully
*inefficient* user-defined comparator", there is no evidence that
different ECMAScript implementations would sort an array consisting of 
strings more efficiently than the sortETA() function. Hasty generalization.

See 
<https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort>


> That said, due to your careless reading your answer does not address
> the question at all; which is basically how to sort using two sort
> keys (which should rather be a topic for “Programming 101”).

You needn't be so unpleasant. And until here, you have missed the point
altogether.


> The simplest answer to that is, for example (for ascending order in
> both cases):
>
> tempArray.sort(function (a, b) { /* first key */ var ax = a.x; var bx
> = b.x;
>
> if (ax < bx) { return -1; }
>
> if (ax > bx) { return 1; }
>
> /* else ax == bx */
>
> /* second key */ var ay = a.y; var by = b.y;
>
> if (ay < by) { return -1; }
>
> if (ay > by) { return 1; }
>
> return 0; });
>
> In this case it can be slightly optimized to
>
> tempArray.sort(function (a, b) { /* first key */ var ax = a.x; var bx
> = b.x;
>
> /* * assuming ax and bx are Number values or convertible; *
> alternative: * *   var diff = ax - bx; *   if (diff) { return diff;
> } */ if (ax != bx) { return ax - bx; }
>
> /* else ax == bx */
>
> /* second key, non-numeric */ var ay = a.y; var by = b.y;
>
> if (ay < by) { return -1; }
>
> if (ay > by) { return 1; }
>
> return 0; });
>
> Of course, thanks to the bracket property accessor and loops this can
> be generalized, which has been done before.

ACK.

-- 
Joao Rodrigues (J.R.)

[toc] | [prev] | [next] | [standalone]


#18785

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-03-09 13:01 +0100
Message-ID<2369961.HIm05VUU83@PointedEars.de>
In reply to#18781
Joao Rodrigues (J.R.) wrote:

> On 05/03/2013 13:51, Thomas 'PointedEars' Lahn wrote:
>> Or you could make Date objects out of the string values (see
>> previous discussions) and sort those.  For example, if you can be
>> sure that the implementation is one of ECMAScript Edition 5 or 5.1,
>> you could replace “/” with “-” and “ ” with “T” and pass that to the
>> Date constructor, because the result is the simplified ISO 8601 time
>> format supported by those implementations (ES 5.1, §15.9.1.5), and
>> Date values of the same time zone sort easily because converting them
>> to Number yields their time value (see also those discussions).
>>
> 
> Theoretical. Remember the code will run in the client-side, while the
> page could be accessed by users from different time zones, or by users
> that have their computers' clocks set to different time zones (which is
> common in maritime companies). Red herring and Argumentum verbosium.

No, *your* argument is the fallacy.  Nobody said where the string values 
come from; they may very well be coming from the server side.  The point is 
that the string values are in a specific format, so you can use that fact to 
your advantage.  Either transform it to a format supported by the Date 
constructor (if you can guarantee that for the target environments), so that 
you can sort time values of Date instances, …

>>> However, you'd be better off testing for the expected ETA string
>>> format passed as the arguments to the sortETA(), using regular
>>> expressions: test whether you have the expected number of digits,
>>> spaces etc. for the date and time parts of the string)
>>
>> Or you could get just the minimum clue and learn that this particular
>> date format (with leading zeroes and fixed length) can be sorted as a
>> string, i.e. *without* such an awfully *inefficient* user-defined
>> comparator:
>>
>> var arr = ['2013/03/06 10:23:01', '2013/03/05 23:59:01', '2013/03/06
>> 00:00:59', '2013/03/05 22:15:00']; arr.sort();

… or sort the strings verbatim if the parts are in positional order, as 
here.
 
> This is known as /defensive programming/.

No, your approach is known as bloat programming.  One simply does not use a 
user-defined comparator when the built-in one suffices.  In this case, all 
values are *strings* (consisting of Unicode characters within the BMP), and 
the array is not sparse, so the built-in comparator suffices.

> As to the "awfully *inefficient* user-defined comparator", there is no
> evidence that different ECMAScript implementations would sort an array
> consisting of strings more efficiently than the sortETA() function.

It suffices to know that for a user-defined comparator you have to create 
another Function instance, and with *your* approach you have to create even 
more objects in the comparator, to know that this approach must be less 
memory-efficient than using the built-in comparator.

It suffices to know that a user-defined function must be called, and that 
*your* comparator does a lot more than “===”, “<”, and “>” comparisons, to 
know that it must be less runtime-efficient than the built-in algorithm.

Therefore, that approach is less efficient than the one that uses the built-
in algorithm.  On top of that, it is less efficient *needlessly* *here*, 
because it provides no additional value *here*.

> Hasty generalization.

Once again you have no clue what you are talking about.  Outside of wannabe 
corners complexity is well enough understood to make the assessment that I 
made about your approach.
 
> See
> <https://developer.mozilla.org/en-
US/docs/JavaScript/Reference/Global_Objects/Array/sort>

Yes, please read that before you post again.  Please read other reference 
material, like the ECMAScript Language Specification, 5.1 Edition, section 
15.4.4.11, too.

>> That said, due to your careless reading your answer does not address
>> the question at all; which is basically how to sort using two sort
>> keys (which should rather be a topic for “Programming 101”).
> 
> You needn't be so unpleasant.

I am merely stating the facts here.  If you do not want to read that you are 
wrong, do not be wrong.

> And until here, you have missed the point altogether.

No, *you* have completely missed the point of the OP which was _not_ how to 
sort date values (in whatever form), but how to use *two* keys for sorting 
an Array.  And you have missed the fact that their dates are in a specific 
format, so in your mistargeted answer you also failed to take advantage of 
that.

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#18728

FromDr J R Stockton <reply1300@merlyn.demon.co.uk.invalid>
Date2013-03-05 21:10 +0000
Message-ID<$GPJ6dJ58lNRFwBo@invalid.uk.co.demon.merlyn.invalid>
In reply to#18714
In comp.lang.javascript message <kh2lrk$ena$1@dont-email.me>, Mon, 4 Mar
2013 18:33:57, Tony <tony.johansson@inport.com> posted:

>I have an array called tempArray that consist of these fields
>VesselID, ETATime, Gotref, Point
>
>When I want to sort on VesselID I use which works good
>tempArray.sort(function (a, b)
>{
>       return a.VesselID - b.VesselID
>})
>
>
>Now I still want to sort on VesselID but within VesselID I also want to
>sort on ETATime
>ETATime which is of format YYYY/MM/DD hh:mm:ss
>
>How can I do that ?

If VesselID.toString() is of constant length, you might be able to use

        return a.toString() - b.toString()

if you do not mind the possibility of resolving matches by sorting on
later fields.

-- 
(c) John Stockton, nr London UK. Mail, see homepage.  DOS 3.3, 6.20; WinXP, 7.
   Web  <http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
   PAS EXE TXT ZIP via  <http://www.merlyn.demon.co.uk/programs/00index.htm>
   My DOS  <http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web