Craig Morgan
Craig Morgan

Reputation: 962

Javascript object array sort returns apparantly random results

I am trying to get a simple sort working on an object array but it seems to be returning completely random results. Please have a look at this plunk: (in FF or Chrome)

http://plnkr.co/edit/TqoyUJV4nzvC4hAkVRkz?p=preview

    var data;
    var asc;

    function init(){
        data = [{username:"leonhaas"},{username:"0johnson"},{username:"leonlang"},{username:"0lechner"},{username:"0koller"},{username:"leonwinkler"},{username:"0schmidt"},{username:"0mueller"},{username:"0schmid"},{username:"lillyfuchs"},{username:"alexandragruber"},{username:"alexanderlechner"},{username:"alexanderpichler"},{username:"alexandraeder"},{username:"lillyreiter"},{username:"alibauer"},{username:"alexandrahall"},{username:"alexandrajohnson"},{username:"alexandrataylor"},{username:"alexandrawilliams"},{username:"lilywinkler"},{username:"alinabauer"},{username:"aliceegger"},{username:"alicesteiner"},{username:"alicewallner"},{username:"aliegger"},{username:"alifuchs"},{username:"linajohnson"},{username:"amarwhite"},{username:"alinaleitner"},{username:"alinaschmidt"},{username:"alinawood"},{username:"alischneider"}];
        outputData(data);
        asc = true;
    }

    function sortIt()
    {
        a = data.username;
        b = data.username;
        if(asc){
            data.sort(function(a,b)
            {
                return 1;
            });
        } else {
            data.sort(function(a,b)
            {
                return -1;
            });
        }

        outputData(data);
    }

    function outputData(data){
        var output = "";
        data.forEach(function (item){
            output += item.username +"<br>";
        });

        var x=document.getElementById("demo");
        x.innerHTML=output;
    }

Upvotes: 1

Views: 166

Answers (5)

Alexey Odintsov
Alexey Odintsov

Reputation: 1715

        data = [{username: "leonhaas"},...];

        var asc = true;

        data.sort(function(a, b) {
            if (asc)
                return a.username > b.username ? 1 : -1;
            else
                return a.username > b.username ? -1 : 1;
        });

        for (var i = 0; i < data.length; i++) {
            console.log(data[i].username);
        }

Upvotes: 0

trrrrrrm
trrrrrrm

Reputation: 11812

function sortIt()
    {
        a = data.username;
        b = data.username;
        if(asc){
            data.sort(function(a,b)
            {
                if(a.username.localeCompare(b.username) > 0)
                return 1;
                else
                return -1;
            });
        } else {
            data.sort(function(a,b)
            {
                if(b.username.localeCompare(a.username) > 0)
                return 1;
                else
                return -1;
            });
        }

        outputData(data);
    }

Upvotes: 0

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76395

A couple of things, you're not sorting the array, you need to return 0 if the values are the same, and then -1 (or 1) depending onascending/descending sorting.
Apart from that, you're assigning var a and var b in your sortIt function, true enough, but those aren't the values you'll be using in the sort callback. Because the arguments of the callback are the same name, they mask the a and b variables of the higher scope.

All things considered, the sort callback should look like this:

data.sort(function(a,b)
{
    return a.username === b.username ? 0 : a.username >b.username ? 1 : -1;
});

All things considered, your code can do with a lot more work: you're using global variables all over the place, your sortIt function will redeclare the sorting callbacks on each call, you're binding event handlers in HTML (always best to manage JS listeners in JS, sort-of Single Responsability-Principle), calling functions that could benefit from an actual relevant call-context etc... look into IIFE's to create closures for a start, and bookmark MDN

Upvotes: 1

Molecular Man
Molecular Man

Reputation: 22386

In your sorting function you have to compare data objects' usernames:

function sortIt()
{
    if(asc){
        data.sort(function(a,b)
        {
            return a.username.localeCompare(b.username);
        });
    } else {
        data.sort(function(a,b)
        {
            return b.username.localeCompare(a.username);
        });
    }

    outputData(data);
}

Upvotes: 4

mohkhan
mohkhan

Reputation: 12305

You should return the value from the sort function based on the condition and not just 1 or -1. Like this...

// Inside your script.js. Line #14
if(asc){
    data.sort(function(a,b)
    {
        return a>b ? 1 : -1;
    });
} else {
    data.sort(function(a,b)
    {
        return a>b ?-1 : 1;
    });
}

Upvotes: 0

Related Questions