10

I have a JSON object generated based on data stored in a table. I then need to be able to sort it in different ways, but when I do JSON.stringify(array) and try to sort from there it doesn't work. When I try to just do array.sort(); it will change the order, but ultimately doesn't work. I don't have much experience with JSON and how to operate it so I'm not sure what else to try. After sorting it I need to go through and rewrite the table with the selected category in alphabetical order.

The JSON looks like this:

var arr = [{
"Functional Category":"T-Shirt",
"Brand Name":"threadless",
"When Obtained":"Last 3 Months",
"How Obtained":"Purchased",
"How Often Worn":"Monthly",
"Where It's Made":"India",
"Has a Graphic":"Yes"}]

I have a fiddle setup here: http://jsfiddle.net/Skooljester/88HVZ/1/ and I have tried what was suggested here but was unable to make it work.

I have two questions, one: how do I go about accomplishing this, and two: is there a better way to do the sorting?

Community
  • 1
  • 1
ayyp
  • 6,590
  • 4
  • 33
  • 47
  • 5
    Next time please include the relevant code in the question. If jsFiddle goes down (which it sometimes does) your question is incomplete. – Matt Ball Dec 07 '11 at 16:50

7 Answers7

8

see below code ....

function sortObject(o) {
    var sorted = {},
    key, a = [];

    for (key in o) {
        if (o.hasOwnProperty(key)) {
                a.push(key);
        }
    }

    a.sort();

    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
}

Does that help?

MANISHDAN LANGA
  • 2,227
  • 6
  • 29
  • 43
8

First, define a compare function:

function compare(el1, el2, index) {
  return el1[index] == el2[index] ? 0 : (el1[index] < el2[index] ? -1 : 1);
}

Then, to sort the array on the first column, use this:

array.sort(function(el1,el2){
  return compare(el1, el2, "Functional Category")
});

Or, to sort on the first column A-Z, and on the second column Z-A if the first column is equal:

array.sort(function(el1,el2){
  var compared = compare(el1, el2, "Functional Category")
  return compared == 0 ? -compare(el1, el2, "Brand Name") : compared;
});
Bart
  • 2,062
  • 15
  • 19
  • This works great. I ran into a problem getting it to print but solved that. Seen here: http://jsfiddle.net/Skooljester/agcUk/3/ Thank you very much! – ayyp Dec 07 '11 at 17:25
  • 2
    Yeah, I've used your previous jsfiddle to test it, see http://jsfiddle.net/88HVZ/7/ – Bart Dec 07 '11 at 17:39
6

The Mozilla developer documentation has a helpful explanation of the sort function. You can provide a function as a parameter that tells the browser how to do the sort.

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort

Some pseudo-code from that link, with the myArray.sort call added and the function name removed:

myArray.sort(function(a, b) {
  if (a is less than b by some ordering criterion)
     return -1;
  if (a is greater than b by the ordering criterion)
     return 1;
  // a must be equal to b
  return 0;
});

EDIT: It looks like you have a single-element array with an object as the element. Objects are unordered. You have to transform it to an array before it can be sorted. Try this (with the Object.keys and Array.prototype.map functions added via augment.js for older browsers):

var result = Object.keys(myArray[0]).sort().map(function(key) {
    return [key,myArray[0][key]];
});

This will give you a sorted, nested array of the form:

[["Brand Name","threadless"],
 ["Function Category","T-Shirt"],
 ...
]
Roy Tinker
  • 10,044
  • 4
  • 41
  • 58
2

Something of this kind might be on help:

function (obj) {
   var a = [],x;
   for(x in obj){ 
     if(obj.hasOwnProperty(x)){
         a.push([x,obj[x]]);
     }
   }
   a.sort(function(a,b){ return a[0]>b[0]?1:-1; })
   return a;
}

Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
1

If your intent is to allow the user to sort the table dynamically, then my approach may be slightly different.

There are plenty of jQuery table sorting plugins. I have had good success with this one: http://tablesorter.com/docs/

Allows multi-column sort, a default sort, wire up to events, etc... etc...

This way you can build your table as you already are, and sorting can be done secondary even before page output.

Betard Fooser
  • 526
  • 5
  • 14
  • That is the correct intent. However, as I am still learning javascript/jQuery I am trying to make it sort without using a plug-in. – ayyp Dec 07 '11 at 17:10
0

This might be helpful for someone in the future if you want to do deep sorting for json properties (where a property value is also a Json object)

function sortObject(o) {
    var sorted = {},
    key, a = [];

    for (key in o) {
        if (o.hasOwnProperty(key)) {
                a.push(key);
        }
    }

    a.sort();

    for (key = 0; key < a.length; key++) {
        if(typeof o[a[key]] === 'object'){
            sorted[a[key]] = sortObject(o[a[key]]);
        } else{
            sorted[a[key]] = o[a[key]];
        }
        
    }
    return sorted;
}
Ayman Ali
  • 567
  • 4
  • 11
  • Without an actual example, this is not a very helpful answer, which BTW has little to do with the original question. Second, note that object key iteration has no guaranteed order, but see e.g. https://stackoverflow.com/a/5525812/563970. Last, learn about [`Object.keys`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) and [`Object.entries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries). If you must sort objects, those can simplify your approach quite a bit. – Bart Feb 03 '23 at 14:07
-1

You can use this approach too. Used less variable to save few lines here!!

var newArr = [{}]; // just to matching pattern with Que variable here
Object.keys(arr[0]).sort().forEach(s => {
    newArr[0][s] = arr[0][s];
})

console.log(newArr);

Output:

[{
  "Brand Name": "threadless",
  "Functional Category": "T-Shirt",
  "Has a Graphic": "Yes",
  "How Obtained": "Purchased",
  "How Often Worn": "Monthly",
  "When Obtained": "Last 3 Months",
  "Where It's Made": "India"
}]
Ajay Gupta
  • 2,867
  • 23
  • 28
  • That just sorts the keys in 1 item (`arr[0]` is a strong hint here), not multiple items. Also, manually constructing an array from another array should be done using `.map`, not `.forEach` into a new array. – Bart Feb 03 '23 at 13:53