JavaScript core bug: Array.sort
-
softmoonwebware last edited by
try this:
<script>
myArray=['one', 'two', 'three', 'four', 'five', 'six', 'seven'];myArray.sort(function(a, b) {
if (a==='three') return 1;
if (b==='three') return -1;
else return 0; });console.log(myArray.toString());
</script>outputs:
['one', 'four', 'two', 'five', 'six', 'seven', 'three']
should be as Chrome says:
['one', 'two', 'four', 'five', 'six', 'seven', 'three']if we change (1) to (-1) and (-1) to (1) in the sort function, the correct result occurs:
['three', 'one', 'two', 'four', 'five', 'six', 'seven']hmmm...how can I write a serious application knowing that I cannot even trust the basic JavaScript engine? Layout engines are ridiculously complicated, so I give any browser slack on that to an extent (I still think Opera had the best until Blink leveled the field). But this is so fundamental, I must become seriously skeptical about allowing, say, my ==Bank== website to even trust the JSengine to produce the correct results. No wonder I have trouble even logging into my cPanel account with Opera...
Remember Opera 10? Ahead of the game, and it respected the high-contrast color-scheme of my Windows desktop.
With 11, it all started to go downhill...mixing desktop foreground colors with preset hardcoded background colors yielding unreadable favorites and other menus, unreadable popup boxes, etc... And from there...? Well, gotta eat here sometime; I could bellyache on this site for hours... -
serious last edited by
opera version maybe? generally I am not sure what your sorting function is supposed to do ... it def. does not sort the elements in any conventional way and seems to somehow rely on the underlying algorithm, which
I am not sure ifis not guaranteed, so a bogus sorting function like yours - which does not compare the elements but just matches them against a predefined value - is not guaranteed to give you the same results in different engines. -
missingno last edited by
To my understanding, it "sorts" 'three' to the end or beginning of the array. However, all other elements are not sorted at all. I would have to check if array.sort is said to be stable (in a way the elements keep the predefined order), but seeing it isn't the case here, I doubt so.
If you want to write a serious application, you should not rely on JavaScript at all because it is a client-side thing, that can be easily manipulated.
-
serious last edited by
Originally posted by missingno:
If you want to write a serious application, you should not rely on JavaScript at all because it is a client-side thing, that can be easily manipulated.
wrong ... though server side validation for user input (once it gets submitted) is never wrong
anyhow, if you want to get a known element to the end of the list without influencing the rest of the elements, doing a strange kind-of-sort like here is not the way of doing it (as sorting is sorting) - a better (in all aspects) approach would be to extract the element and append it at the end.
-
softmoonwebware last edited by
Originally posted by serious:
wrong ... though server side validation for user input (once it gets submitted) is never wrong
anyhow, if you want to get a known element to the end of the list without influencing the rest of the elements, doing a strange kind-of-sort like here is not the way of doing it (as sorting is sorting) - a better (in all aspects) approach would be to extract the element and append it at the end.
Well, your Bank has a web-portal. You transfer money through it. To me that is a very serious application.
I'm just writing a color-picker now, and a bitmap-graphics generator that can do things with gradients that your $500 desktop software fumbles with, if it can do it at all. Not a replacement altogether, just delivering advanced features. To me this is a serious application. Not just dancing bears across the screen to draw attention to the latest sale. If the bears skip a step here and there because the JavaScript language implementation doesn't even know how to implement a basic sort (wasn't that algorithm perfected in, like, 1957?) no one has a heartbreak except the graphic designer. My application simply doesn't work correctly. That is a real problem to me.
Sure I can loop through the entire array, find the position of the matching element, use Array.slice() to slice it out, Array.push() to append it to the end as I want. That's a lot of work for the interpreter, more characters of code to transfer, etc. Not much more, but a business owner once told me: watch your pennies, the dollars watch themselves. Coming from a background of writing Assembly Language for computers with 32K of available memory instilled a passion for writing optimized code. And in the technical definition of sort, I am sorting the one item as being _less_ than all the others, in this case. But the technical definition of sort says that when two items are deemed equal, their order should not change! In my case, I can simply identify, slice and push, but what if I was doing a more complex sort? Technical specs are there for a reason. If a JavaScript interpreter does not follow them, how can you write cross-browser code?
But now I have to worry that Array.slice() and push() and the for(){} loop and the === operator are always reliable. I mean if they skrew up something as basic as a sort, what else is untrusted?
I was telling someone my job isn't writing software, it's being a detective. OK, why doesn't this work here, but does here. Usually it's a browser layout issue: they all have their idiosyncrasies. Like I said, that is an incredibly complex task, with a constantly evolving and changing algorithm. I give them all slack (granted, MSIE takes a mile of slack, when I offer a yard, but that's another story) But sorting an Array? That should be child's play. Computer Programming 100 in high-school.
When I have to spend an hour or half a day going through 3000 lines of incredibly complex code to find MY error, when really it is the _core_ JavsScript interpreter, all I can say $%^@#!
I was using Opera as my desktop browser, as well as my developmental browser, getting my code to work with Opera first and then cross-browser testing it, usually requiring a change in the CSS. I'm thinking more and more about Chrome, now that they've merged -webkit- with Opera's code to create Blink, my current project displays correctly on Chrome under all circumstances (even MSIE was doing better), although it inherited some bugs that are more minor to my project that it didn't have before.
But the _core_ JavaScript sort function?????? PS using Opera 12.16 - the most current stable release offered automatically to my system, with auto-update enabled.
-
sgunhouse Moderator Volunteer last edited by
12.16 is Presto, and will not be updated further. Opera 15 through 20 (so far) are based on Google's Blink engine, and will obviously produce the same results as Chrome. Yes, that's right - I did say 12.16 will not update to the latest stable version (18 ... 19 and 20 are still in development), you have to install it manually.
But as missingno says, since your sort does not order any element other than "three", Opera's answer is not wrong.
-
missingno last edited by
Originally posted by softmoonwebware:
If a JavaScript interpreter does not follow them, how can you write cross-browser code?
Like I said ECMAScript neither dictates a specific sorting algorithm, nor expects it to be stable.
Originally posted by softmoonwebware:
And in the technical definition of sort, I am sorting the one item as being _less_ than all the others, in this case.
Which gives you the correct result (as both are correct).
Originally posted by softmoonwebware:
But the technical definition of sort says that when two items are deemed equal, their order should not change!
Wrong. That only goes for stable sorting algorithmns. If stability isn't an issue, you can achieve better runtime and/or memory usage using an unstable sorting algorithmn. But as a writer of assembly language code you sure know that, right?
Fun fact: InsertionSort and MergeSort (used by Apple and Mozilla) are stable, QuickSort (Google Chrome) is not (by default). Chrome will sort arrays using InsertionSort if the array has 10 or less elements. So I suppose your code abovewillmay give another result if using 11 or more items in the array in Chrome. (Or Google already changed to another sorting algorithmn.)Originally posted by softmoonwebware:
Well, your Bank has a web-portal. You transfer money through it. To me that is a very serious application.
My bank has a web-portal that doesn't rely on JavaScript.
-
softmoonwebware last edited by
If I have an array of things my customers ordered:
orders=[
{count: 4, name: "John", item: "foo"},
{count: 7, name: "Jack", item: "bar"},
{count: 12, name: "Kelly", item: "baz"},
{count: 4, name: "Bob", item: "bar"},
{count: 3, name: "Tim", item: "buz"},
{count: 7, name: "Sara", item: "bar"} ]now I sort them by customer name:
orders.sort(function(a,b) {
if (a.name<b.name) return -1;
if (a.name>b.name) return 1;
else return 0; });I expect:
orders===[
{count: 4, name: "Bob", item: "bar"},
{count: 7, name: "Jack", item: "bar"},
{count: 4, name: "John", item: "foo"},
{count: 12, name: "Kelly", item: "baz"},
{count: 7, name: "Sara", item: "bar"},
{count: 3, name: "Tim", item: "buz"} ]Now I take the array and sort it further by number of items ordered, so I can fill my big$$$ orders first:
orders.sort(function(a,b) {return a.count-b.count;});I expect the names to remain ordered when the count is the same:
orders===[
{count: 3, name: "Tim", item: "buz"},
{count: 4, name: "Bob", item: "bar"},
{count: 4, name: "John", item: "foo"},
{count: 7, name: "Jack", item: "bar"},
{count: 7, name: "Sara", item: "bar"},
{count: 12, name: "Kelly", item: "baz"} ]In a situation where my program requires and relies on two-step ordering (perhaps two separate functions are called in order, with the choice of functions dependent on program state, to deliver a final ordering) Opera will fail.
-
softmoonwebware last edited by
reply to missingno:
points taken.
but points given, also.
At what point can we then create browser-based cross-platform applications when one JavaScript engine takes the "slack" road?
That is what modern HTML5 - ECMAScript 5 browsers are supposed to be about, yea?
So then my complaint is that Opera is just slack.
-
softmoonwebware last edited by
Originally posted by sgunhouse:
12.16 is Presto, and will not be updated further. Opera 15 through 20 (so far) are based on Google's Blink engine, and will obviously produce the same results as Chrome. Yes, that's right - I did say 12.16 will not update to the latest stable version (18 ... 19 and 20 are still in development), you have to install it manually.
But as missingno says, since your sort does not order any element other than "three", Opera's answer is not wrong.
OHHHH so that's why I'm wondering about Opera 17 references.
Seems I even browsed "recently" to opera.com and did not find anything that said Opera 17.
how lame is that? My browser won't even tell me there is something better going on. Instead it tells me _Oh, you're up to date!_
So when I update to 17 (a link or hint from the Opera moderator would have been nice) will it delete all my favorites as updates in the past have? I lost a lot of old links that were important to me going from 10 to 11; despite repeated bug notices 11 to 12, 12.0 to 12.1, all deleted my favorites. By then I backed up regularly, and turned OFF auto-update, only update notice.
Will Opera 17 allow me to use high-definition desktop colors? Or will its interface show me yellow letters on a white background?
The bright-white screen is hard on my eyes. -
A Former User last edited by
Originally posted by softmoonwebware:
My browser won't even tell me there is something better going on.
There's not. Opera 12.16 is still the most recent version of Opera for Presto. Opera 18 is the latest version for Blink, but it is still missing most of the features that make Opera better than other browsers.
-
softmoonwebware last edited by
Hey! It didn't loose my bookmarks!
Why? It doesn't even HAVE bookmarks!
Absolutely useless browser Opera 18 is.
Force me to use YOUR pictures via a theme? LAME and SLACK.
No tab-control?
I want tabs to be grouped together.
I want a newly opened tab to be active (why wouldn't I, I just opened it?!?)JUNK
-
softmoonwebware last edited by
Originally posted by Pesala:
Originally posted by softmoonwebware:
My browser won't even tell me there is something better going on.
There's not. Opera 12.16 is still the most recent version of Opera for Presto. Opera 18 is the latest version for Blink, but it is still missing most of the features that make Opera better than other browsers.
It is missing features that make Opera decent browser at all, let alone a better one.
-
A Former User last edited by
- It does have a bookmarks bar. Please search the forum for 100s of previous threads
- You can select new themes and create your own
- Tab-grouping would be nice.
- Open new tabs in the background is weird indeed. Shift + Click or Middle-click can be used.
-
serious last edited by
aaanyhow, we are already flaming 15+ in enough other threads, so btt (though I think that has been exhaustively discussed) or lets close the thread.
PS: OT: "relying on js" discussion: There is a distinct difference between relying on JS (as in: webapp using only an API to communicate with the server) which is not a big deal these days vs. relying on JS for validation of user input (which is very bad).
-
softmoonwebware last edited by
Originally posted by serious:
aaanyhow, we are already flaming 15+ in enough other threads, so btt (though I think that has been exhaustively discussed) or lets close the thread.
PS: OT: "relying on js" discussion: There is a distinct difference between relying on JS (as in: webapp using only an API to communicate with the server) which is not a big deal these days vs. relying on JS for validation of user input (which is very bad).
I just want to create a desktop application that never even needs a server.
But I may want to create an application that does most of its work on the browser, unloading the server, to deliver some pieces of data, secure or not. Securing data sent to the browser has nothing to do with JavaScript. I can forge a web form response with or without JavaScript. But if I want to process the data on-page (not necessarily validating it without server validation) I need JavaScript to function reliably. Again, point taken on what is and is not the real spec, and what I expected.Originally posted by Pesala:
- It does have a bookmarks bar. Please search the forum for 100s of previous threads
- You can select new themes and create your own
- Tab-grouping would be nice.
- Open new tabs in the background is weird indeed. Shift + Click or Middle-click can be used.
I really must be blind. I still don't see any bookmarks bar options going through all menus, right clicking everywhere, etc. But I'll spend another 2 hours going through all the bellyaching posts to find the answer. Oh wait, I DID, and still don't have a clue where to find it. Perhaps you would be kind enough to point me to the right discussion that actually gives instructions as to where to find this functionality.
And I specifically looked for a way to create my own theme, but not finding a link in Opera's menu, nor a link on the site to download theme, I felt like my time was better spent than to try to outguess the poorly conceived and designed user-interface and documentation of Opera 18. -
softmoonwebware last edited by
Originally posted by Pesala:
- It does have a bookmarks bar. Please search the forum for 100s of previous threads
- You can select new themes and create your own
- Tab-grouping would be nice.
- Open new tabs in the background is weird indeed. Shift + Click or Middle-click can be used.
In the "Where are the Opera 18 bookmarks post" you give advice that does NOT work in the copy of Opera 18 that I just downloaded. I can import 1000 bookmarks to my speed-dial, but there is NO bookmarks bar offered to import to.
-
frenzie last edited by
Originally posted by missingno:
Fun fact: InsertionSort and MergeSort (used by Apple and Mozilla) are stable, QuickSort (Google Chrome) is not (by default). Chrome will sort arrays using InsertionSort if the array has 10 or less elements. So I suppose your code above
willmay give another result if using 11 or more items in the array in Chrome. (Or Google already changed to another sorting algorithmn.)I thought Opera/Presto 10+ is also stable. Although I guess the OP proves that wrong?
Originally posted by softmoonwebware:
I expect:
orders===[
{count: 4, name: "Bob", item: "bar"},
{count: 7, name: "Jack", item: "bar"},
{count: 4, name: "John", item: "foo"},
{count: 12, name: "Kelly", item: "baz"},
{count: 7, name: "Sara", item: "bar"},
{count: 3, name: "Tim", item: "buz"} ]Now I take the array and sort it further by number of items ordered, so I can fill my big$$$ orders first:
orders.sort(function(a,b) {return a.count-b.count;});I expect the names to remain ordered when the count is the same:
orders===[
{count: 3, name: "Tim", item: "buz"},
{count: 4, name: "Bob", item: "bar"},
{count: 4, name: "John", item: "foo"},
{count: 7, name: "Jack", item: "bar"},
{count: 7, name: "Sara", item: "bar"},
{count: 12, name: "Kelly", item: "baz"} ]In a situation where my program requires and relies on two-step ordering (perhaps two separate functions are called in order, with the choice of functions dependent on program state, to deliver a final ordering) Opera will fail.
Umm, all of that works exactly that way in Opera 12.16 for me.
-
softmoonwebware last edited by
Originally posted by Frenzie:
Originally posted by softmoonwebware:
I expect:
orders===[
{count: 4, name: "Bob", item: "bar"},
{count: 7, name: "Jack", item: "bar"},
{count: 4, name: "John", item: "foo"},
{count: 12, name: "Kelly", item: "baz"},
{count: 7, name: "Sara", item: "bar"},
{count: 3, name: "Tim", item: "buz"} ]Now I take the array and sort it further by number of items ordered, so I can fill my big$$$ orders first:
orders.sort(function(a,b) {return a.count-b.count;});I expect the names to remain ordered when the count is the same:
orders===[
{count: 3, name: "Tim", item: "buz"},
{count: 4, name: "Bob", item: "bar"},
{count: 4, name: "John", item: "foo"},
{count: 7, name: "Jack", item: "bar"},
{count: 7, name: "Sara", item: "bar"},
{count: 12, name: "Kelly", item: "baz"} ]In a situation where my program requires and relies on two-step ordering (perhaps two separate functions are called in order, with the choice of functions dependent on program state, to deliver a final ordering) Opera will fail.
Umm, all of that works exactly that way in Opera 12.16 for me.
Gotta admit I never tried it. But then it must be how that specific Array-arrangement ends up sorting anyway; when the Array has more or less entries, or a different starting order, will it still work? If the original example that started this post changes the original order due to lazy-quick algorithms, then it MAY change any other ordered-Array that has random entries and random ordering functions.
But if Opera 18 were just a descent browser as a user's browser goes, then the comment by the moderator would be relevant, that Opera 18 is NOT lazy. But I won't be using 18 because it doesn't even have bookmarks! How many others will still use 12.16 like me? When will HTML5 applications be truly possible? Why would Opera release a less-powerful browser that should be a BETA release for testing, not the primary download available for new users? The answers are all blowing in the wind... -
frenzie last edited by
Originally posted by softmoonwebware:
How many others will still use 12.16 like me?
Most of the posters in this thread. Possibly even all if you replace 12.16 with Presto.