5

Before you tag this as duplicate - I've gone through these answers:

Sort JSON by array key value

Sort a JSON array object using Javascript by value

And I've tried moving the code over to my data, and it doesn't work. I've tried pushing each object item into an array as well, but that doesn't work because there's still an object inside each item.

Here's a bit of the JSON response I get (screenshot from the browser console)

As you can see, each item has an index - what I need is to sort the response according to the index. How do I do this?

This response is from wikipedia - as an aside. Here's the full API call, if it helps.

EDIT: Posting a bit of the response code here:

 "pages": {
      "736": {
        "pageid": 736,
        "ns": 0,
        "title": "Albert Einstein",
        "index": 2,
        "contentmodel": "wikitext",
        "pagelanguage": "en",
        "pagelanguagehtmlcode": "en",
        "pagelanguagedir": "ltr",
        "touched": "2018-01-24T22:40:11Z",
        "lastrevid": 821432412,
        "length": 145560,
        "fullurl": "https://en.wikipedia.org/wiki/Albert_Einstein",
        "editurl": "https://en.wikipedia.org/w/index.php?title=Albert_Einstein&action=edit",
        "canonicalurl": "https://en.wikipedia.org/wiki/Albert_Einstein",
        "thumbnail": {
          "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Einstein_1921_by_F_Schmutzer_-_restoration.jpg/38px-Einstein_1921_by_F_Schmutzer_-_restoration.jpg",
          "width": 38,
          "height": 50
        },
        "pageimage": "Einstein_1921_by_F_Schmutzer_-_restoration.jpg"
      },
      "983": {
        "pageid": 983,
        "ns": 0,
        "title": "Albert Camus",
        "index": 10,
        "contentmodel": "wikitext",
        "pagelanguage": "en",
        "pagelanguagehtmlcode": "en",
        "pagelanguagedir": "ltr",
        "touched": "2018-01-26T09:34:35Z",
        "lastrevid": 822358239,
        "length": 53639,
        "fullurl": "https://en.wikipedia.org/wiki/Albert_Camus",
        "editurl": "https://en.wikipedia.org/w/index.php?title=Albert_Camus&action=edit",
        "canonicalurl": "https://en.wikipedia.org/wiki/Albert_Camus",
        "thumbnail": {
          "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Albert_Camus%2C_gagnant_de_prix_Nobel%2C_portrait_en_buste%2C_pos%C3%A9_au_bureau%2C_faisant_face_%C3%A0_gauche%2C_cigarette_de_tabagisme.jpg/42px-Albert_Camus%2C_gagnant_de_prix_Nobel%2C_portrait_en_buste%2C_pos%C3%A9_au_bureau%2C_faisant_face_%C3%A0_gauche%2C_cigarette_de_tabagisme.jpg",
          "width": 42,
          "height": 50
        },
        "pageimage": "Albert_Camus,_gagnant_de_prix_Nobel,_portrait_en_buste,_posé_au_bureau,_faisant_face_à_gauche,_cigarette_de_tabagisme.jpg"
      },
      "46721": {
        "pageid": 46721,
        "ns": 0,
        "title": "Edward VII",
        "index": 9,
        "contentmodel": "wikitext",
        "pagelanguage": "en",
        "pagelanguagehtmlcode": "en",
        "pagelanguagedir": "ltr",
        "touched": "2018-01-26T02:00:27Z",
        "lastrevid": 821663314,
        "length": 81925,
        "fullurl": "https://en.wikipedia.org/wiki/Edward_VII",
        "editurl": "https://en.wikipedia.org/w/index.php?title=Edward_VII&action=edit",
        "canonicalurl": "https://en.wikipedia.org/wiki/Edward_VII",
        "thumbnail": {
          "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Edward_VII_in_coronation_robes.jpg/35px-Edward_VII_in_coronation_robes.jpg",
          "width": 35,
          "height": 50
        },
        "pageimage": "Edward_VII_in_coronation_robes.jpg"
      }
firefiber
  • 155
  • 1
  • 2
  • 10
  • 1
    Can you post the JSON object you're trying to sort in code form instead of an image? – devius Jan 26 '18 at 11:04
  • 2
    If you want to do something so specific that no other question here solves your issue, shouldn't you tell us what you want to do and why those other techniques do not apply? – Álvaro González Jan 26 '18 at 11:04
  • by what do you want so sort which array? – Nina Scholz Jan 26 '18 at 11:05
  • @devius The response was pretty huge, which is why I didn't post into the body - but I've done it now :) @NinaScholz by the `index`. It's not an array unfortunately, it's a JSON response I get, and I want a way to sort this response by the `index` that each item in the object has. – firefiber Jan 26 '18 at 11:08
  • So, why you've put this title *Sort JSON response by key value* – Ele Jan 26 '18 at 11:15
  • You can't sort an object by its keys. The other answers you linked to will have informed you of this. – Andy Jan 26 '18 at 11:17
  • @Andy I'm aware of that yes, but there's a way to convert the object into an array, and then sort it from there. I've tried doing this and kept hitting an error on the console. I also read on the MediaWiki API on several pages where they explicitly stated that sorting can be done client-side. And so here I am. – firefiber Jan 26 '18 at 11:29
  • Maybe so, but your question didn't say that. – Andy Jan 26 '18 at 11:30
  • The numeric keys in an object are already sorted, so you can't get a new object no matter how you insert it. The only thing you can do is to sort the values. – Hassan Imam Jan 26 '18 at 11:46

3 Answers3

2

Your response seems to be an object, which can't be sorted. You first want to convert it into an array

const res = //... your response
const array = Object.keys(res).map(key => res[key]);

Now you can use the Array.sort function to sort your items by their index:

array.sort((itemA, itemB) =>  itemA - itemB)

Be aware that the sort function directly mutates the array.

See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Scarysize
  • 4,131
  • 25
  • 37
  • I wish I could understand why your code worked, and the previous ones I tried did not. To push into an array, I tried: ` let arr = []; for (let key in obj){ arr.push([key, obj[key]]); }` And then tried the same sort method, but I kept running into an error. – firefiber Jan 26 '18 at 11:23
  • What was the error? In your case you are pushing an array into an array. In my example you will push objects into an array. – Scarysize Jan 26 '18 at 11:42
  • My solution in your terms is basically: `for(let key in obj) { arr.push(obj[key])}`. Though the `for..in` is kind of unsafe to use, see: https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea – Scarysize Jan 26 '18 at 11:46
2

I created these functions to order a json so that it would also work if there was another json inside it.

function orderJson(json) {
    let ordered = this.jsonToSortedArray(json);
    let result = this.arrayToStringJson(ordered);
    return JSON.parse(result);
}

function jsonToSortedArray(json) {
    let ordered = [];
    for (let i in json) {
        let value;
        if (json[i] instanceof Object) {
            value = jsonToSortedArray(json[i]);
        } else {
            value = json[i];
        }
        ordered.push([i, value]);
    }
    return ordered.sort();
}

function arrayToStringJson(ordered) {
    let result = '{'
    for (let i = 0; i < ordered.length; i++) {
        const key = '"' + ordered[i][0] + '"';
        let value;
        if (ordered[i][1] instanceof Array) {
            value = ':' + this.arrayToStringJson(ordered[i][1]) + ',';
        } else {
            value = ':"' + ordered[i][1] + '",';
        }
        result += key + value;
    }
    result = result.substring(0, result.length - 1);
    return result + '}';
}

If you want the json as a string do not use the function JSON.parse

Cafeteru_
  • 71
  • 5
1

This is my approach, just convert to an array and then get back the JSON Object.

UPDATE: What I did was create an array of every page then using the Array.prototype.sort() function for Arrays I compared the index for each page then using a for-loop I recreated the JSON object using the objects within the sorted Array.

var json = {
  "pages": {
    "983": {
      "pageid": 983,
      "ns": 0,
      "title": "Albert Camus",
      "index": 10,
      "contentmodel": "wikitext",
      "pagelanguage": "en",
      "pagelanguagehtmlcode": "en",
      "pagelanguagedir": "ltr",
      "touched": "2018-01-26T09:34:35Z",
      "lastrevid": 822358239,
      "length": 53639,
      "fullurl": "https://en.wikipedia.org/wiki/Albert_Camus",
      "editurl": "https://en.wikipedia.org/w/index.php?title=Albert_Camus&action=edit",
      "canonicalurl": "https://en.wikipedia.org/wiki/Albert_Camus",
      "thumbnail": {
        "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Albert_Camus%2C_gagnant_de_prix_Nobel%2C_portrait_en_buste%2C_pos%C3%A9_au_bureau%2C_faisant_face_%C3%A0_gauche%2C_cigarette_de_tabagisme.jpg/42px-Albert_Camus%2C_gagnant_de_prix_Nobel%2C_portrait_en_buste%2C_pos%C3%A9_au_bureau%2C_faisant_face_%C3%A0_gauche%2C_cigarette_de_tabagisme.jpg",
        "width": 42,
        "height": 50
      },
      "pageimage": "Albert_Camus,_gagnant_de_prix_Nobel,_portrait_en_buste,_posé_au_bureau,_faisant_face_à_gauche,_cigarette_de_tabagisme.jpg"
    },
    "736": {
      "pageid": 736,
      "ns": 0,
      "title": "Albert Einstein",
      "index": 2,
      "contentmodel": "wikitext",
      "pagelanguage": "en",
      "pagelanguagehtmlcode": "en",
      "pagelanguagedir": "ltr",
      "touched": "2018-01-24T22:40:11Z",
      "lastrevid": 821432412,
      "length": 145560,
      "fullurl": "https://en.wikipedia.org/wiki/Albert_Einstein",
      "editurl": "https://en.wikipedia.org/w/index.php?title=Albert_Einstein&action=edit",
      "canonicalurl": "https://en.wikipedia.org/wiki/Albert_Einstein",
      "thumbnail": {
        "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Einstein_1921_by_F_Schmutzer_-_restoration.jpg/38px-Einstein_1921_by_F_Schmutzer_-_restoration.jpg",
        "width": 38,
        "height": 50
      },
      "pageimage": "Einstein_1921_by_F_Schmutzer_-_restoration.jpg"
    }
  }
};

var array = [];
for (key in json.pages) {
  array.push(json.pages[key]);
}

array.sort(function(a, b) {
  return a.index - b.index;
});

json = {
  "pages": {}
};

for (var i = 0; i < array.length; i++) {
  json.pages[array[i]['pageid']] = array[i];
}

console.log(json);

Hope it helps!

Ele
  • 33,468
  • 7
  • 37
  • 75
  • Thanks for taking the time to reply! Just a quick question: Works perfectly! Just wish I could understand why it's working. – firefiber Jan 26 '18 at 11:40