2

I'm working on javascript dealer search functionality: http://www.example.com/kw_haendlersuche_bug

Try type "74564" in "Adresse" field and press enter. Result will be sorted list of dealers by distance.

On IE11 result will be different than on other browsers.

The key part of dealersearch_de_bug.js (line 166):

var c_sort = function(a, b) {
    return a.dist - b.dist;
};
markers.sort(c_sort);

But when I sort it twice - http://www.example.com/kw_haendlersuche

dealersearch_de.js line 166:

var c_sort = function(a, b) {
    return a.dist - b.dist;
};
markers.sort(c_sort);
markers.sort(c_sort);

Result is different and close to the result from other browsers.

What is going on?

10
  • why not use return a.dist - b.dist;? Commented May 28, 2015 at 8:05
  • No difference, I've tried both. Commented May 28, 2015 at 8:11
  • 1
    Have you looked at how they are different? If 2 markers have the same dist, you cannot guarantee the order they will appear, and sorting twice will most likely give a different sort order Commented May 28, 2015 at 8:17
  • 1
    Array.sort() works on the given array. no assigment required. Commented May 28, 2015 at 8:28
  • 1
    It looks like your website overloaded the main Array constructor. It's possible one of the additional functions being added (e.g., _each) is used in IE's sorting. You're also loading dozens of scripts from different places (all.js is being loaded twice, by the way), so without spending an hour poking around I couldn't even locate what library is doing that. In your place, the first thing I'd do is try to turn that off and see if IE behavior changed. Commented May 28, 2015 at 9:35

1 Answer 1

2

One of the elements in your markers array has a NaN value for the dist property. (It's markers[482] in your current test case.) This is throwing off IE's sort() function - and in other browsers too.

If you remove any such markers from your array before sorting, then it sorts correctly. You could do this with an if( ! isNaN(distance) ) test where you create the var current and push it to the markers array.

I also agree with Curtis's comment about the libraries modifying Array.prototype - that can be dangerous because two libraries may step on each other. That isn't the cause of this particular problem though - the same error occurs if you sort the markers array in a vanilla test page with no libraries. Here is a simple example:

<!doctype html>
<html>
<head>
    <title>Sort Test</title>
</head>
<body>
    <script>
        function log( array, text ) {
            document.write(
                '[ ' + array.join(', ') + ' ] ' + text + '<br>'
            );
        }

        var array = [ 3, 9, NaN, 5, 4 ];
        log( array, 'original' );
        array.sort( function( a, b ) { return a - b; } );
        log( array, 'sorted' );
    </script>
</body>
</html>

When I load this page in IE11 it displays:

[ 3, 9, NaN, 5, 4 ] original
[ 3, 4, 9, NaN, 5 ] sorted

It also fails to sort correctly in Chrome:

[ 3, 9, NaN, 5, 4 ] original
[ 3, 9, NaN, 4, 5 ] sorted

and Firefox:

[ 3, 9, NaN, 5, 4 ] original
[ 4, 5, NaN, 3, 9 ] sorted

I suspect that your page was also not sorting correctly in the other browsers but was just "close enough" - unless for some reason the NaN value did not appear in those browsers.

Why does the NaN value mess up sorting so badly? Well, sorting depends on being able to compare any two values of an array and get consistent results: less than, greater than, or equal.

But NaN doesn't work like an ordinary number. You can compare any value with NaN and the result is always false, no matter what the comparison is - even if you compare with the same NaN value:

console.log( NaN == NaN );  // false!

Similarly if you add or subtract NaN in an expression, you always get NaN as a result. All of this wreaks havoc with a sort function, whether it uses comparisons or subtraction.

Sign up to request clarification or add additional context in comments.

1 Comment

not only NaN makes funny things, as well as objects with absent properties.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.