Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #19552 > unrolled thread
| Started by | "Tony" <tony.johansson@inport.com> |
|---|---|
| First post | 2013-05-01 17:18 +0200 |
| Last post | 2013-05-04 16:14 +0100 |
| Articles | 16 — 7 participants |
Back to article view | Back to comp.lang.javascript
About keeping my array 1 based after having sorted it "Tony" <tony.johansson@inport.com> - 2013-05-01 17:18 +0200
Re: About keeping my array 1 based after having sorted it Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-05-01 08:26 -0700
Re: About keeping my array 1 based after having sorted it "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2013-05-01 19:43 +0200
Re: About keeping my array 1 based after having sorted it Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-05-01 15:15 -0700
Re: About keeping my array 1 based after having sorted it "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2013-05-02 09:35 +0200
Re: About keeping my array 1 based after having sorted it Denis McMahon <denismfmcmahon@gmail.com> - 2013-05-02 14:31 +0000
Re: About keeping my array 1 based after having sorted it Denis McMahon <denismfmcmahon@gmail.com> - 2013-05-01 22:12 +0000
Re: About keeping my array 1 based after having sorted it "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2013-05-02 09:36 +0200
Re: About keeping my array 1 based after having sorted it Scott Sauyet <scott.sauyet@gmail.com> - 2013-05-02 08:52 -0700
Re: About keeping my array 1 based after having sorted it Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-05-03 01:26 +0200
Re: About keeping my array 1 based after having sorted it Scott Sauyet <scott.sauyet@gmail.com> - 2013-05-03 08:53 -0700
Re: About keeping my array 1 based after having sorted it Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-05-03 18:39 +0200
Re: About keeping my array 1 based after having sorted it Scott Sauyet <scott.sauyet@gmail.com> - 2013-05-03 11:00 -0700
Sorting arrays of objects (was: About keeping my array 1 based after having sorted it) Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-05-05 01:00 +0200
Re: Sorting arrays of objects (was: About keeping my array 1 based after having sorted it) Scott Sauyet <scott.sauyet@gmail.com> - 2013-05-05 08:53 -0700
Re: About keeping my array 1 based after having sorted it Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-05-04 16:14 +0100
| From | "Tony" <tony.johansson@inport.com> |
|---|---|
| Date | 2013-05-01 17:18 +0200 |
| Subject | About keeping my array 1 based after having sorted it |
| Message-ID | <klrbhd$duk$1@dont-email.me> |
I use a 1 based array because I need to find each record that is a multiple
of three later in the code.
After I have used this sort below the array is then back to use zero based.
I can handle this in his way
for (var i = 0; i < bookingArray.length; i++)
{
a[++j] = bookingArray[i];
}
bookingArray = a;
but I just wonder if I can make the sort to keep my 1 based array ?
bookingArray.sort(function (a, b)
{
var aObjectid = a.Objectid;
var bObjectid = b.Objectid;
var aFromtime = new Date(a.Fromtime);
var bFromtime = new Date(b.Fromtime);
if (aObjectid == bObjectid)
return (aFromtime < bFromtime) ? -1 : (aFromtime
> bFromtime) ? 1 : 0;
else
return (aObjectid < bObjectid) ? -1 : 1;
});
//Tony
[toc] | [next] | [standalone]
| From | Daniel Pitts <newsgroup.nospam@virtualinfinity.net> |
|---|---|
| Date | 2013-05-01 08:26 -0700 |
| Message-ID | <guagt.23460$zH4.10295@newsfe13.iad> |
| In reply to | #19552 |
On 5/1/13 8:18 AM, Tony wrote:
> I use a 1 based array because I need to find each record that is a
> multiple of three later in the code.
> After I have used this sort below the array is then back to use zero based.
>
> I can handle this in his way
> for (var i = 0; i < bookingArray.length; i++)
> {
> a[++j] = bookingArray[i];
> }
> bookingArray = a;
>
> but I just wonder if I can make the sort to keep my 1 based array ?
>
> bookingArray.sort(function (a, b)
> {
> var aObjectid = a.Objectid;
> var bObjectid = b.Objectid;
>
> var aFromtime = new Date(a.Fromtime);
> var bFromtime = new Date(b.Fromtime);
>
> if (aObjectid == bObjectid)
> return (aFromtime < bFromtime) ? -1 :
> (aFromtime > bFromtime) ? 1 : 0;
> else
> return (aObjectid < bObjectid) ? -1 : 1;
> });
>
> //Tony
If you put a dummy value at the front of the array that is always before
any other value, that'll keep it where you want.
Alternatively, instead of using 1 base, use 0 base and when you need
"every third element", for (var i = 2; i < bookingArray.length; i+=3)
[toc] | [prev] | [next] | [standalone]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2013-05-01 19:43 +0200 |
| Message-ID | <XnsA1B3C892E7F06eejj99@194.109.133.133> |
| In reply to | #19553 |
Daniel Pitts wrote on 01 mei 2013 in comp.lang.javascript:
> Alternatively, instead of using 1 base, use 0 base and when you need
> "every third element", for (var i = 2; i < bookingArray.length; i+=3)
>
for (var i = 0; i < bookingArray.length/3; i++)
x = bookingArray[i * 3 + 1];
--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
[toc] | [prev] | [next] | [standalone]
| From | Daniel Pitts <newsgroup.nospam@virtualinfinity.net> |
|---|---|
| Date | 2013-05-01 15:15 -0700 |
| Message-ID | <Jtggt.32252$2b6.23400@newsfe10.iad> |
| In reply to | #19555 |
On 5/1/13 10:43 AM, Evertjan. wrote: > Daniel Pitts wrote on 01 mei 2013 in comp.lang.javascript: > >> Alternatively, instead of using 1 base, use 0 base and when you need >> "every third element", for (var i = 2; i < bookingArray.length; i+=3) >> > > for (var i = 0; i < bookingArray.length/3; i++) > x = bookingArray[i * 3 + 1]; works well enough for a one based array. The multiply and add inside the loop make the C programmer in me cringe. Anyway, your addition to this thread was completely irrelevant to the OPs question.
[toc] | [prev] | [next] | [standalone]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2013-05-02 09:35 +0200 |
| Message-ID | <XnsA1B4618E3BD9eejj99@194.109.133.133> |
| In reply to | #19558 |
Daniel Pitts wrote on 02 mei 2013 in comp.lang.javascript:
> On 5/1/13 10:43 AM, Evertjan. wrote:
>> Daniel Pitts wrote on 01 mei 2013 in comp.lang.javascript:
>>
>>> Alternatively, instead of using 1 base, use 0 base and when you need
>>> "every third element", for (var i = 2; i < bookingArray.length; i+=3)
>>>
>>
>> for (var i = 0; i < bookingArray.length/3; i++)
>> x = bookingArray[i * 3 + 1];
+ 2];
> works well enough for a one based array. The multiply and add inside
> the loop make the C programmer in me cringe.
>
> Anyway, your addition to this thread was completely irrelevant to the
> OPs question.
1/
This is not a helpdesk. Your irrelevancy is quite irrelevant.
2/
This is not about C.
There is no compiled code to be kept and kept short.
The loss of speed/cpu-time will only be apparent in heavy use,
not expected in clientside browser programming.
[In serverside Javascript, I would suggest using a database, not an array]
3/
It can be easily extended to:
for (var i = 0; i < bookingArray.length/3; i++) {
x = bookingArray[i * 3 + 1];
y = bookingArray[i * 3 + 2];
z = bookingArray[i * 3 + 3];
...
};
4/
The above 3/ shows the weakness in the OQ specification
of the need for a 1-based array:
for (var i = 0; i < bookingArray.length/3; i++) {
x = bookingArray[i * 3 + 0];
y = bookingArray[i * 3 + 1];
z = bookingArray[i * 3 + 2];
...
};
5/
or even the weakness of the supposed simplicity
of an 1-dimensional array here:
var betterArray = [];
for (var i = 0; i < bookingArray.length/3; i++) {
betterArray[i] = [
bookingArray[i * 3 + 0],
bookingArray[i * 3 + 1],
bookingArray[i * 3 + 2]
];
};
var bookingNr = 37; // 1-based if still required
var lastName = 1; // constant
alert( 'lastName' = betterArray[bookingNr-1][lastName] );
--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2013-05-02 14:31 +0000 |
| Message-ID | <klttcq$m0v$2@dont-email.me> |
| In reply to | #19568 |
On Thu, 02 May 2013 09:35:24 +0200, Evertjan. wrote:
> The above 3/ shows the weakness in the OQ specification of the need for
> a 1-based array:
Indeed, the OP might be better off using an array of objects, where each
object contained 3 values, and he could:
function booking( a, b ) {
this.a = a; this.b = b; this.c = 0;
}
function make_booking( a, b, bookings ) {
bookings.push( new booking( a, b ) );
return bookings;
}
function some_function( x, y ) {
var z;
/* code goes here */
return z;
}
function update_bookings( bookings ) {
var i;
for ( i = 0; i < bookings.length; i++ )
if ( bookings[i].c == 0 )
bookings[i].c = some_function( bookings[i].a, bookings[i].b );
return bookings;
}
Of course, that code will get horribly distorted now, but whatever ;)
--
Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2013-05-01 22:12 +0000 |
| Message-ID | <kls3vj$6b7$4@dont-email.me> |
| In reply to | #19555 |
On Wed, 01 May 2013 19:43:01 +0200, Evertjan. wrote: > Daniel Pitts wrote on 01 mei 2013 in comp.lang.javascript: > >> Alternatively, instead of using 1 base, use 0 base and when you need >> "every third element", for (var i = 2; i < bookingArray.length; i+=3) >> >> > for (var i = 0; i < bookingArray.length/3; i++) > x = bookingArray[i * 3 + 1]; I think the last "+ 1" should be +2 0 indexed, the first element he wants (with i = 0) is element [2] (the third element) but x above will be element [1] when i = 0 ( 0 * 3 + 1 ) -- Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2013-05-02 09:36 +0200 |
| Message-ID | <XnsA1B461B90ACBCeejj99@194.109.133.133> |
| In reply to | #19559 |
Denis McMahon wrote on 02 mei 2013 in comp.lang.javascript: > On Wed, 01 May 2013 19:43:01 +0200, Evertjan. wrote: > >> Daniel Pitts wrote on 01 mei 2013 in comp.lang.javascript: >> >>> Alternatively, instead of using 1 base, use 0 base and when you need >>> "every third element", for (var i = 2; i < bookingArray.length; i+=3) >>> >>> >> for (var i = 0; i < bookingArray.length/3; i++) >> x = bookingArray[i * 3 + 1]; > > I think the last "+ 1" should be +2 > > 0 indexed, the first element he wants (with i = 0) is element [2] (the > third element) > > but x above will be element [1] when i = 0 ( 0 * 3 + 1 ) Indeed. -- Evertjan. The Netherlands. (Please change the x'es to dots in my emailaddress)
[toc] | [prev] | [next] | [standalone]
| From | Scott Sauyet <scott.sauyet@gmail.com> |
|---|---|
| Date | 2013-05-02 08:52 -0700 |
| Message-ID | <c0affca3-9adb-40c0-bcdd-3222defbd338@a8g2000yqp.googlegroups.com> |
| In reply to | #19552 |
Tony wrote:
> I use a 1 based array because I need to find each record that is a multiple
> of three later in the code.
That really should not cause any difficulty with standard arrays.
Others have already addressed this in their responses.
> bookingArray.sort(function (a, b)
> {
> var aObjectid = a.Objectid;
> var bObjectid = b.Objectid;
>
> var aFromtime = new Date(a.Fromtime);
> var bFromtime = new Date(b.Fromtime);
>
> if (aObjectid == bObjectid)
> return (aFromtime < bFromtime) ? -1 : (aFromtime
> > bFromtime) ? 1 : 0;
> else
> return (aObjectid < bObjectid) ? -1 : 1;
> });
That sort function looks quite verbose. (You might also want to look
at the FAQ section on posting [1] for the formatting preferences of
the group.)
You can probably achieve the same thing with this:
bookingArray.sort(function(a, b) {
return a.Objectid < b.Objectid ? -1 :
a.Objectid > b.Objectid ? +1 :
new Date(a.Fromtime) - new Date(b.Fromtime);
});
And if the Objectid properties are numeric, you can get even simpler:
bookingArray.sort(function(a, b) {
return a.Objectid - b.Objectid ||
new Date(a.Fromtime) - new Date(b.Fromtime);
});
-- Scott
[1] http://jibbering.com/faq/#posting
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-05-03 01:26 +0200 |
| Message-ID | <12786665.ZbpLptdNGN@PointedEars.de> |
| In reply to | #19584 |
Scott Sauyet wrote:
> You can probably achieve the same thing with this:
>
> bookingArray.sort(function(a, b) {
> return a.Objectid < b.Objectid ? -1 :
> a.Objectid > b.Objectid ? +1 :
> new Date(a.Fromtime) - new Date(b.Fromtime);
(The “+” in “+1” is a superfluous conversion operation; it is *not* a no-op.
Also, few people know that “-1” actually is a “unary -” conversion operation
on the primitive Number value 1. See ES 5.1, §§ 11.4.6 and 11.4.7.)
Please do not write or suggest such code; it is a maintenance nightmare.
Write such code if you want your colleagues to dislike you for it, put
politely. See also: <http://stackoverflow.com/q/14693135/855543>
The least you should do is using parentheses to group the expressions to
make it easier to read and to debug, for example (preferred by me)
return (a.Objectid < b.Objectid
? -1
: (a.Objectid > b.Objectid
? 1
: new Date(a.Fromtime) - new Date(b.Fromtime)));
or (preferred by others)
return (a.Objectid < b.Objectid)
? -1
: (a.Objectid > b.Objectid)
? 1
: new Date(a.Fromtime) - new Date(b.Fromtime);
As the conversion to Date appears to be superfluous here¹, there is also
var comparator = jsx.array.getComparator(
["Objectid", "Fromtime"], {numeric: true});
bookingArray.sort(comparator);
(see
<http://PointedEars.de/websvn/filedetails.php?repname=JSX&path=/trunk/array.js>)
The least you should do is cache the comparator.
> });
>
> And if the Objectid properties are numeric, you can get even simpler:
>
>
> bookingArray.sort(function(a, b) {
> return a.Objectid - b.Objectid ||
> new Date(a.Fromtime) - new Date(b.Fromtime);
> });
Again, indicating the operator precedence is a good idea:
bookingArray.sort(function (a, b) {
return (a.Objectid - b.Objectid)
|| (new Date(a.Fromtime) - new Date(b.Fromtime));
});
or (more efficient here)
bookingArray.sort(function (a, b) {
return (a.Objectid - b.Objectid) || (a.Fromtime - b.Fromtime);
});
It should also be noted that using the “||” operator carries with it the
internal conversion of the first operand to Boolean which may be more
expensive than other approaches.
______
¹ However, this gives me the idea that it could be useful that
jsx.array.getComparator() could also be passed a callback or constructor
for each key, or all keys, whose return value would be used as operand
in the comparison. What do you think?
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Scott Sauyet <scott.sauyet@gmail.com> |
|---|---|
| Date | 2013-05-03 08:53 -0700 |
| Message-ID | <bd93fc08-185a-4614-91c2-a78ea5b6beaa@n11g2000yqe.googlegroups.com> |
| In reply to | #19605 |
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> You can probably achieve the same thing with this:
>
>> bookingArray.sort(function(a, b) {
>> return a.Objectid < b.Objectid ? -1 :
>> a.Objectid > b.Objectid ? +1 :
>> new Date(a.Fromtime) - new Date(b.Fromtime);
>
> (The “+” in “+1” is a superfluous conversion operation; it is *not* a no-op.
ACK.
But I choose to accept the very minor performance degradation in order
to keep the code more obvious, stressing that I'm returning a positive
number in one place and a negative in another.
> Also, few people know that “-1” actually is a “unary -” conversion operation
> on the primitive Number value 1. See ES 5.1, §§ 11.4.6 and 11.4.7.)
What's your evidence for that? I'm surprised to learn that few people
know that. Do they expect it's simply part of the number literal
instead?
> Please do not write or suggest such code; it is a maintenance nightmare.
> Write such code if you want your colleagues to dislike you for it, put
> politely. See also: <http://stackoverflow.com/q/14693135/855543>
While I do usually avoid nested ternary statements, this type of sort
function, because of their extreme simplicity, are often an exception.
> The least you should do is using parentheses to group the expressions to
> make it easier to read and to debug, for example (preferred by me)
>
> return (a.Objectid < b.Objectid
> ? -1
> : (a.Objectid > b.Objectid
> ? 1
> : new Date(a.Fromtime) - new Date(b.Fromtime)));
>
> or (preferred by others)
>
> return (a.Objectid < b.Objectid)
> ? -1
> : (a.Objectid > b.Objectid)
> ? 1
> : new Date(a.Fromtime) - new Date(b.Fromtime);
I find both of those harder to read than my suggestion. Can you
suggest any objective criteria that makes those suggestions easier to
read or debug?
> As the conversion to Date appears to be superfluous here¹, there is also
I don't think so. The OP didn't here specify the type of `Fromtime`,
but several recent posts from the OP discussed dates parsed out of
strings. I remember for instance, something like "2013-05-03 11:00"
in a recent post. Since we don't know that we can get rid of them, I
kept them in.
> var comparator = jsx.array.getComparator(
> ["Objectid", "Fromtime"], {numeric: true});
>
> bookingArray.sort(comparator);
>
> (see
> <http://PointedEars.de/websvn/filedetails.php?repname=JSX&path=/trunk/...>)
That looks to be very useful.
> The least you should do is cache the comparator.
I'm not sure what you're suggesting. Of course the comparator is
supplied as a single reference to the `sort` call. And there was no
hint that the data needed to be sorted again later. Of course if were
to be, the same function should probably be supplied to sort. But
that's irrelevant to any issue at hand as far as I can see.
>> And if the Objectid properties are numeric, you can get even simpler:
>
>> bookingArray.sort(function(a, b) {
>> return a.Objectid - b.Objectid ||
>> new Date(a.Fromtime) - new Date(b.Fromtime);
>> });
>
> Again, indicating the operator precedence is a good idea:
>
> bookingArray.sort(function (a, b) {
> return (a.Objectid - b.Objectid)
> || (new Date(a.Fromtime) - new Date(b.Fromtime));
> });
Those parentheses neither add nor detract for me. I certainly don't
object. Stylistically, I prefer to keep the `||` on the first line,
but other than that, either one is fine, and I would probably choose
the parentheses if I hadn't dashed this off in three minutes.
> or (more efficient here)
>
> bookingArray.sort(function (a, b) {
> return (a.Objectid - b.Objectid) || (a.Fromtime - b.Fromtime);
> });
See above. I'm guessing that `Fromtime` is a string.
> It should also be noted that using the “||” operator carries with it the
> internal conversion of the first operand to Boolean which may be more
> expensive than other approaches.
Perhaps, but we all know about premature optimization...
> ______
> ¹ However, this gives me the idea that it could be useful that
> jsx.array.getComparator() could also be passed a callback or constructor
> for each key, or all keys, whose return value would be used as operand
> in the comparison. What do you think?
I'm not sure what you would mean by "or all keys" unless you mean for
each independently, but other than that, I can see that this would be
a useful option. If the objects you want to sort have a property more
complex than a String or Number but that still has an intrinsic order,
it would be nice to be able to include that in your comparator. But
rather than a callback/constructor, how about recursively applying
another comparator for that key?
-- Scott
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-05-03 18:39 +0200 |
| Message-ID | <4320221.o7mTL0IePv@PointedEars.de> |
| In reply to | #19607 |
Scott Sauyet wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> You can probably achieve the same thing with this:
>>> bookingArray.sort(function(a, b) {
>>> return a.Objectid < b.Objectid ? -1 :
>>> a.Objectid > b.Objectid ? +1 :
>>> new Date(a.Fromtime) - new Date(b.Fromtime);
>>
>> (The “+” in “+1” is a superfluous conversion operation; it is *not* a
>> no-op.
>
> ACK.
>
> But I choose to accept the very minor performance degradation in order
> to keep the code more obvious, stressing that I'm returning a positive
> number in one place and a negative in another.
KISS: Numbers that have no negative sign are positive. (Yes, I know about
zero.)
>> Also, few people know that “-1” actually is a “unary -” conversion
>> operation on the primitive Number value 1. See ES 5.1, §§ 11.4.6 and
>> 11.4.7.)
>
> What's your evidence for that?
I remember to have observed this misconception several times before.
> I'm surprised to learn that few people know that. Do they expect it's
> simply part of the number literal instead?
Apparently so. I would expect many people to be surprised that
var x = {-1: "foo"};
is syntactically wrong, while
var x = {1: "foo"};
is correct, as it is somewhat counter-intuitive. (A number is a number,
isn't it?)
>> Please do not write or suggest such code; it is a maintenance nightmare.
>> Write such code if you want your colleagues to dislike you for it, put
>> politely. See also: <http://stackoverflow.com/q/14693135/855543>
>
> While I do usually avoid nested ternary statements, this type of sort
> function, because of their extreme simplicity, are often an exception.
Of course. The problem is not the Conditional *Operator* (_not_ “ternary
statements”).
>> The least you should do is using parentheses to group the expressions to
>> make it easier to read and to debug, for example (preferred by me)
>>
>> return (a.Objectid < b.Objectid
>> ? -1
>> : (a.Objectid > b.Objectid
>> ? 1
>> : new Date(a.Fromtime) - new Date(b.Fromtime)));
>>
>> or (preferred by others)
>>
>> return (a.Objectid < b.Objectid)
>> ? -1
>> : (a.Objectid > b.Objectid)
>> ? 1
>> : new Date(a.Fromtime) - new Date(b.Fromtime);
>
> I find both of those harder to read than my suggestion. Can you
> suggest any objective criteria that makes those suggestions easier to
> read or debug?
Yes. As for reading, the parentheses make it clear what are either the
conditional expressions or the conditions of those expressions. As for
debugging, each value is on its own line, therefore this code is easier to
debug step-by-step with debuggers that debug by line instead of by
expression.
>> var comparator = jsx.array.getComparator(
>> ["Objectid", "Fromtime"], {numeric: true});
>>
>> bookingArray.sort(comparator);
>>
>> (see
>>
<http://PointedEars.de/websvn/filedetails.php?repname=JSX&path=/trunk/...>)
>
> That looks to be very useful.
Thank you.
>> or (more efficient here)
>>
>> bookingArray.sort(function (a, b) {
>> return (a.Objectid - b.Objectid) || (a.Fromtime - b.Fromtime);
>> });
>
> See above. I'm guessing that `Fromtime` is a string.
Previous threads started by the same person on the same problem (BTW a bad
idea) suggest that it is a Number value.
>> ______
>> ¹ However, this gives me the idea that it could be useful that
>> jsx.array.getComparator() could also be passed a callback or constructor
>> for each key, or all keys, whose return value would be used as operand
>> in the comparison. What do you think?
>
> I'm not sure what you would mean by "or all keys" unless you mean for
> each independently,
Currently you can configure the sort method (numeric or generic), sort order
(ascending or descending), and strictness (strict or loose equality) of the
sorting both for each key separately and for all keys specified in the
factory call. The same approach would be applied to the
callback/constructor options.
> but other than that, I can see that this would be a useful option.
ACK
> If the objects you want to sort have a property more complex than a String
> or Number but that still has an intrinsic order, it would be nice to be
> able to include that in your comparator. But rather than a
> callback/constructor, how about recursively applying another comparator
> for that key?
I do not see how this could work. The elements of the Array are to be
sorted by a property of the objects referred by the Array elements; the
properties of the object's that are referred by the Array's elements are not
to be modified.
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Scott Sauyet <scott.sauyet@gmail.com> |
|---|---|
| Date | 2013-05-03 11:00 -0700 |
| Message-ID | <42a7e3a8-0fc0-4a5d-8809-312503f14f28@z10g2000yqd.googlegroups.com> |
| In reply to | #19614 |
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> or (more efficient here)
>
>>> bookingArray.sort(function (a, b) {
>>> return (a.Objectid - b.Objectid) || (a.Fromtime - b.Fromtime);
>>> });
>
>> See above. I'm guessing that `Fromtime` is a string.
>
> Previous threads started by the same person on the same problem (BTW a bad
> idea) suggest that it is a Number value.
Interesting, as I had looked to other threads by the same poster and
drew a different conclusion. Obviously if they are numbers, the Date
constructor is not necessary...
I'm guessing we're not going to come to any agreement on the code
style discussions, but I would like to address the following:
>>> ______
>>> ¹ However, this gives me the idea that it could be useful that
>>> jsx.array.getComparator() could also be passed a callback or constructor
>>> for each key, or all keys, whose return value would be used as operand
>>> in the comparison. What do you think?
>
>> I'm not sure what you would mean by "or all keys" unless you mean for
>> each independently,
>
> Currently you can configure the sort method (numeric or generic), sort order
> (ascending or descending), and strictness (strict or loose equality) of the
> sorting both for each key separately and for all keys specified in the
> factory call. The same approach would be applied to the
> callback/constructor options.
Yes, I did understand the code. I just didn't see how supplying the
same constructor or callback for all properties would be useful.
Which means, I think, that I'm probably misunderstanding in general.
>> but other than that, I can see that this would be a useful option.
>
> ACK
>
>> If the objects you want to sort have a property more complex than a String
>> or Number but that still has an intrinsic order, it would be nice to be
>> able to include that in your comparator. But rather than a
>> callback/constructor, how about recursively applying another comparator
>> for that key?
>
> I do not see how this could work. The elements of the Array are to be
> sorted by a property of the objects referred by the Array elements; the
> properties of the object's that are referred by the Array's elements are not
> to be modified.
Perhaps I'm misunderstanding your suggestion. My idea is probably
best given with an example. If you had an array of objects structured
something like this:
myCar {
year: 2003,
manufacturer: "Dodge",
make: "Neon",
color: "red",
engine: {
liters: 2.0,
cylinders: 4
},
doors: 4
// ...
}
Then I might want to make a comparator with code something like this
(please forgive me if I misuse your API; I haven't actually tried it):
var myComparator = jsx.array.getComparator([
"year",
"manufacturer",
"model",
{
key: "engine",
comparator: jsx.array.getComparator([
"cylinders",
"liters"
])
}
]);
That internal `getComparator` call was what I was suggesting. It
seems to me to be a great way of offereing additional flexibility. Is
this similar to what you wanted to do? Would it cover the same
ground? It's clearly not as powerful as offering an arbitrary
function, but it might do much of what one would want to with such a
function, no?
-- Scott
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-05-05 01:00 +0200 |
| Subject | Sorting arrays of objects (was: About keeping my array 1 based after having sorted it) |
| Message-ID | <9570287.vLAVuxmI2c@PointedEars.de> |
| In reply to | #19626 |
Scott Sauyet wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> ______
>>>> ¹ However, this gives me the idea that it could be useful that
>>>> jsx.array.getComparator() could also be passed a callback or
>>>> constructor for each key, or all keys, whose return value would be used
>>>> as operand in the comparison. What do you think?
>>>
>>> I'm not sure what you would mean by "or all keys" unless you mean for
>>> each independently,
>>
>> Currently you can configure the sort method (numeric or generic), sort
>> order (ascending or descending), and strictness (strict or loose
>> equality) of the sorting both for each key separately and for all keys
>> specified in the factory call. The same approach would be applied to the
>> callback/constructor options.
>
> Yes, I did understand the code. I just didn't see how supplying the
> same constructor or callback for all properties would be useful.
> Which means, I think, that I'm probably misunderstanding in general.
[This method, which is a (Function) factory, is now
jsx.array.createComparator() to avoid confusion with getters.]
If the values of all (sort) keys are of the same type, and they are to be
compared as if they were of another type, it should not be necessary to
write
var comparator = jsx.array.createComparator([
{key: "x", callback: myConverter},
{key: "y", callback: myConverter}
{key: "z", callback: myConverter}
]);
instead of
var comparator = jsx.array.createComparator(["x", "y", "z"], {
callback: myConverter
});
Same for “constructor” and “comparator”. DRY.
>>> If the objects you want to sort have a property more complex than a
>>> String or Number but that still has an intrinsic order, it would be nice
>>> to be able to include that in your comparator. But rather than a
>>> callback/constructor, how about recursively applying another comparator
>>> for that key?
>>
>> I do not see how this could work. The elements of the Array are to be
>> sorted by a property of the objects referred by the Array elements; the
>> properties of the object's that are referred by the Array's elements are
>> not to be modified.
>
> Perhaps I'm misunderstanding your suggestion.
ISTM you understand correctly.
> My idea is probably best given with an example. If you had an array of
> objects structured something like this:
>
> myCar {
> year: 2003,
> manufacturer: "Dodge",
> make: "Neon",
> color: "red",
> engine: {
> liters: 2.0,
> cylinders: 4
> },
> doors: 4
> // ...
> }
>
> Then I might want to make a comparator with code something like this
> (please forgive me if I misuse your API; I haven't actually tried it):
>
> var myComparator = jsx.array.getComparator([
> "year",
> "manufacturer",
> "model",
> {
> key: "engine",
> comparator: jsx.array.getComparator([
> "cylinders",
> "liters"
> ])
> }
> ]);
>
> That internal `getComparator` call was what I was suggesting. It
> seems to me to be a great way of offereing additional flexibility.
Yes, that is a Good Idea. It is easier to implement and use, and more
efficient than having the outer comparator iterate over subkeys.
Implemented.
> Is this similar to what you wanted to do? Would it cover the same
> ground? It's clearly not as powerful as offering an arbitrary
> function, but it might do much of what one would want to with such a
> function, no?
[It turns out that one can eat this cake *and* have it.]
If the “callback” property is specified, the original sort value is
converted by passing the value to it, and using its return value as the new
sort value.
If the “constructor” (own) property is specified, the original or previous
sort value is converted by passing it to the constructor, and using the
returned object value as the new sort value.
If the “comparator” property is specified, it takes precedence over the
default comparison, using the original sort value or one of the previous
sort values. If either the outer key is the last key, or if the inner
comparator returns a value not equal to 0, the return value of the specified
comparator is returned; otherwise the values of the next keys are
considered.
That is,
function Bar (baz)
{
this.baz = String(baz);
}
Bar.prototype.toString = function () {
return this.baz;
};
function Baz (bla)
{
this.length = bla.length;
}
var foo = [
{"bar": new Bar("burpbarbazbla")},
{"bar": new Bar("foo")}
];
var _createComparator = jsx.array.createComparator;
foo.sort(_createComparator(["bar"], {
callback: String,
constructor: Baz,
comparator: _createComparator(["length"], {numeric: true})
}));
results in “foo” holding a reference to the equivalent of
[
{"bar": new Bar("foo")},
{"bar": new Bar("burpbarbazbla")}
]
because:
1a. String(new Bar("burpbarbazbla")) === "burpbarbazbla"
1b. String(new Bar("foo")) === "foo"
2a. new Baz("burpbarbazbla") returns {length: 13} : Baz
2b. new Baz("foo") returns {length: 3} : Baz
3a. new Baz("burpbarbazbla").length === 13
3b. new Baz("foo").length === 3
4. 3 < 13
The unit test is now available at
<http://PointedEars.de/scripts/test/array>.
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Scott Sauyet <scott.sauyet@gmail.com> |
|---|---|
| Date | 2013-05-05 08:53 -0700 |
| Subject | Re: Sorting arrays of objects (was: About keeping my array 1 based after having sorted it) |
| Message-ID | <c6cce191-f2f8-487a-ae89-cb775395730a@r3g2000yqe.googlegroups.com> |
| In reply to | #19635 |
Thomas 'PointedEars' Lahn wrote:
>Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Scott Sauyet wrote:
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>> ______
>>>>> ¹ However, this gives me the idea that it could be useful that
>>>>> jsx.array.getComparator() could also be passed a callback or
>>>>> constructor for each key, or all keys, whose return value would be used
>>>>> as operand in the comparison. What do you think?
>
>>>> I'm not sure what you would mean by "or all keys" unless you mean for
>>>> each independently,
>
>>> Currently you can configure the sort method (numeric or generic), sort
>>> order (ascending or descending), and strictness (strict or loose
>>> equality) of the sorting both for each key separately and for all keys
>>> specified in the factory call. The same approach would be applied to the
>>> callback/constructor options.
>
>> Yes, I did understand the code. I just didn't see how supplying the
>> same constructor or callback for all properties would be useful.
>> Which means, I think, that I'm probably misunderstanding in general.
>
> [This method, which is a (Function) factory, is now
> jsx.array.createComparator() to avoid confusion with getters.]
>
> If the values of all (sort) keys are of the same type, and they are to be
> compared as if they were of another type, it should not be necessary to
> write
>
> var comparator = jsx.array.createComparator([
> {key: "x", callback: myConverter},
> {key: "y", callback: myConverter}
> {key: "z", callback: myConverter}
> ]);
>
> instead of
>
> var comparator = jsx.array.createComparator(["x", "y", "z"], {
> callback: myConverter
> });
>
> Same for “constructor” and “comparator”. DRY.
I do (now) see that could be useful at times. It's interesting how I
imagined almost exactly the same code and saw no reason for it, but as
soon as I saw it written out I could come up with possible uses!
If, for instance, `myConverter` converted Strings to Numbers or
changed the case of Strings, obviously it could be useful for a
comparator. And if I can so easily come up with two such scenarios,
clearly there are many others.
>> [ ... ] My idea is probably best given with an example. [ ... ]
>>
>> var myComparator = jsx.array.getComparator([
>> "year",
>> "manufacturer",
>> "model",
>> {
>> key: "engine",
>> comparator: jsx.array.getComparator([
>> "cylinders",
>> "liters"
>> ])
>> }
>> ]);
>
>> That internal `getComparator` call was what I was suggesting. It
>> seems to me to be a great way of offering additional flexibility.
>
> Yes, that is a Good Idea. It is easier to implement and use, and more
> efficient than having the outer comparator iterate over subkeys.
> Implemented.
And it has the advantage that this internal comparator can be a
reference to one used elsewhere.
>> Is this similar to what you wanted to do? Would it cover the same
>> ground? It's clearly not as powerful as offering an arbitrary
>> function, but it might do much of what one would want to with such a
>> function, no?
>
> [It turns out that one can eat this cake *and* have it.]
>
> If the “callback” property is specified, the original sort value is
> converted by passing the value to it, and using its return value as the new
> sort value.
>
> If the “constructor” (own) property is specified, the original or previous
> sort value is converted by passing it to the constructor, and using the
> returned object value as the new sort value.
>
> If the “comparator” property is specified, it takes precedence over the
> default comparison, using the original sort value or one of the previous
> sort values. If either the outer key is the last key, or if the inner
> comparator returns a value not equal to 0, the return value of the specified
> comparator is returned; otherwise the values of the next keys are
> considered.
> [ ... ]
This is extremely flexible. I'm not sure how often I would need this
flexibility, but it's always nice to know when using an API that the
flexibility is there, so long as it doesn't overly complicate the API.
Nicely done.
-- Scott
[toc] | [prev] | [next] | [standalone]
| From | Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2013-05-04 16:14 +0100 |
| Message-ID | <KBf07lIKXShRFw38@invalid.uk.co.demon.merlyn.invalid> |
| In reply to | #19607 |
In comp.lang.javascript message <bd93fc08-185a-4614-91c2-a78ea5b6beaa@n1
1g2000yqe.googlegroups.com>, Fri, 3 May 2013 08:53:40, Scott Sauyet
<scott.sauyet@gmail.com> posted:
>Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> You can probably achieve the same thing with this:
>>
>>> bookingArray.sort(function(a, b) {
>>> return a.Objectid < b.Objectid ? -1 :
>>> a.Objectid > b.Objectid ? +1 :
>>> new Date(a.Fromtime) - new Date(b.Fromtime);
>>
>> (The “+” in “+1” is a superfluous conversion operation; it is *not* a no-op.
>
>ACK.
>
>But I choose to accept the very minor performance degradation in order
>to keep the code more obvious, stressing that I'm returning a positive
>number in one place and a negative in another.
A sensible system will handle those signs on reading the source or on
first executing the statement. In any case, the time taken to do one of
those should be negligible in comparison with that taken to do the
function call and return.
>> Also, few people know that “-1” actually is a “unary -” conversion operation
>> on the primitive Number value 1. See ES 5.1, §§ 11.4.6 and 11.4.7.)
>
>What's your evidence for that? I'm surprised to learn that few people
>know that. Do they expect it's simply part of the number literal
>instead?
A script engine is required to give the results which would be given if
the specification was followed literally. If there is a formal
requirement to follow the specification literally, it will be ignored in
actual browsers where thought beneficial to do so.
--
(c) John Stockton, nr London, UK. E-mail, see Home Page. Turnpike v6.05.
Website <http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc. : <http://www.merlyn.demon.co.uk/programs/> - see in 00index.htm
Dates - miscdate.htm estrdate.htm js-dates.htm pas-time.htm critdate.htm etc.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web