0

I am trying to order an object that I "converted" from JSON. I'm trying to use this function that I found on this question, but it does not seem to work in my case:

function sortJsonArrayByProperty(objArray, prop, direction){
    if (arguments.length<2) throw new Error("sortJsonArrayByProp requires 2 arguments");
    var direct = arguments.length>2 ? arguments[2] : 1; //Default to ascending

    if (objArray && objArray.constructor===Array){
        var propPath = (prop.constructor===Array) ? prop : prop.split(".");
        objArray.sort(function(a,b){
            for (var p in propPath){
                if (a[propPath[p]] && b[propPath[p]]){
                    a = a[propPath[p]];
                    b = b[propPath[p]];
                }
            }
            // convert numeric strings to integers
            a = a.match(/^\d+$/) ? +a : a;
            b = b.match(/^\d+$/) ? +b : b;
            return ( (a < b) ? -1*direct : ((a > b) ? 1*direct : 0) );
        });
    }
}

And here is my JsFiddle

I want to sort it in 3 different ways:

  • chronologically by dict (using "time" field)
  • Alphabetically by dict (using "term" field")
  • All chronologically (ignore dict separations)

If this object wasn't so nested I would know how to do it. Could I adapt that function?

Community
  • 1
  • 1
Cornwell
  • 3,304
  • 7
  • 51
  • 84
  • Instead of passing the whole object to `sortJsonArrayByProperty`, pass each `terms` array independently. Only for the last way you'd have to combine the two arrays. – Felix Kling Nov 20 '13 at 21:02
  • Please back up and rather than post a piece of code you found and tried, describe what problem you're actually trying to solve. Show us what your data looks like and what you want the sorted output to look like. That's the ONLY way we can properly help you. And, please post that info in your actual question, not in a jsFiddle. In looking at the data in your jsFiddle, it is unclear what exactly you want sorted as there are multiple arrays in there. – jfriend00 Nov 20 '13 at 21:06
  • There's a copy of the obj in the fiddle. – Andy Nov 20 '13 at 21:08
  • @Andy - and it's completely unclear what they want the output to look like. There are multiple arrays in the jsFiddle. For example, there are multiple `terms` arrays. Besides, questions should stand on their own without having to look at a jsFiddle in order to understand what the question is asking. – jfriend00 Nov 20 '13 at 21:09
  • Yeah, hadn't realised how nested that obj was... – Andy Nov 20 '13 at 21:13
  • @jfriend00 I don't know how I could show the object? I added a link to the fiddle since it the object will show in the console in a more readable way. – Cornwell Nov 20 '13 at 21:33
  • @Andy I want to sort everything inside the "main" obj, I mean everything inside the terms objects first. It's hard to explain. I thought showing the object would be easier – Cornwell Nov 20 '13 at 21:35
  • @Cornwell - if it's hard to explain and you actually know what you want, then how could we possibly know what you want? The "clear" way to show the desired output would be to include the javascript data for what you want the output to like after sorted. At the risk of totally wasting my time and rewarding you for an unclear question, I posted a guess to an answer. – jfriend00 Nov 20 '13 at 21:38

1 Answers1

1

You haven't explained the output you want so here's a logical guess based on the data in your jsFiddle.

OK, here's the data from your jsFiddle in an understandable form:

var obj = {saved: [
    {"dict":"English","terms": [
        {"term":"car","rowId":"3487","time":"1384773838069"},
        {"term":"dog","rowId":"443","time":"1384776129957"},
        {"term":"plane","rowId":"16171","time":"1384776168253"},
        {"term":"bread","rowId":"127564","time":"1384959605196"}]
     }, 
     {"dict":"French","terms": [
         {"term":"Monsieur","rowId":"934","time":"1384862250130"},
         {"term":"Croissant","rowId":"13612","time":"1384900161187"},
         {"term":"suis","rowId":"942","time":"1384900437068"}]
      }
    ]
};

I'm assuming that you want to sort each terms array separately by one of the fields in it.

Here's how you could sort it by field:

// utility function for sorting an array by a key in alpha order
function sortArrayAlpha(arr, key) {
    arr.sort(function(a, b) {
        return a[key].localeCompare(b[key]);
    });
}

// utility function for sorting an array by a key in parsed numeric order
function sortArrayNum(arr, key) {
    arr.sort(function(a, b) {
        return parseInt(a[key], 10) - parseInt(b[key], 10);
    });
}

// sort by term
var dicts = obj.saved;
// cycle through each item in the saved array
for (var i = 0; i < dicts.length; i++) {
    var terms = dicts[i].terms;
    sortArrayAlpha(terms, "term");
}

// sort by time
// cycle through each item in the saved array
for (var i = 0; i < dicts.length; i++) {
    var terms = dicts[i].terms;
    sortArrayNum(terms, "time");
}

// sort by rowId
// cycle through each item in the saved array
for (var i = 0; i < dicts.length; i++) {
    var terms = dicts[i].terms;
    sortArrayNum(terms, "rowId");
}

And, a jsFiddle that shows the output: http://jsfiddle.net/jfriend00/vH8u7/. You can see in the jsFiddle the exact output format for each sort.

Here's what sort by term looks like:

{"saved":[
    {"dict":"English","terms":[
        {"term":"bread","rowId":"127564","time":"1384959605196"},
        {"term":"car","rowId":"3487","time":"1384773838069"},
        {"term":"dog","rowId":"443","time":"1384776129957"},
        {"term":"plane","rowId":"16171","time":"1384776168253"}]},
    {"dict":"French","terms":[
        {"term":"Croissant","rowId":"13612","time":"1384900161187"},
        {"term":"Monsieur","rowId":"934","time":"1384862250130"},
        {"term":"suis","rowId":"942","time":"1384900437068"}]
    }
]}
jfriend00
  • 683,504
  • 96
  • 985
  • 979