0

so I have a JSON array that looks like this:

[
  {
    row: [
      {
        boat: {
          description: 'Books',
          version: '2',
          id: 6
        },
        airplanes: [
          {
            airplane: [
              {
                description: 'DVD',
                version: 2,
                uid: 69,
                wid: 65,
                id: 84
              }
            ],
            trains: {
              train: [
                {
                  description: 'Pictures',
                  version: 2,
                  id: 149
                }
              ],
              actions: [
                {
                  description: 'This is a really long sentence.',
                  version: 2,
                  tid: 69.01,
                  id: 452
                },
                {
                  description: 'article 2',
                  version: 2,
                  tid: 69.02,
                  id: 453
                },
                {
                  description: 'developer 1',
                  version: 2,
                  tid: 69.03,
                  id: 454
                }
              ]
            }
          },
          {
            airplane: [
              {
                description: 'Games',
                version: 2,
                uid: 65,
                wid: 61,
                id: 80
              }
            ],
            trains: {
              train: [
                {
                  description: 'another great descriptions.',
                  version: 2,
                  id: 145
                }
              ],
              actions: [
                {
                  description: 'being indecisive is good.',
                  version: 2,
                  tid: 65.01,
                  id: 442
                },
                {
                  description: 'couches are comfortable',
                  version: 2,
                  tid: 65.02,
                  id: 443
                }
              ]
            }
          }
        ]
      }
    ]
  }
]

I am trying to sort the above output by 'wid' in ascending order but still be able to preserve the overall order. For example in the above the wid in element 0 of the array is 65, and element 1 of the array the wid value is 61. Therefore, element 1 and element 0 should be swapped. Is there any built in javascript method to sort json like this?

I will have a json array output a lot larger than the provided example.

adbarads
  • 1,253
  • 2
  • 20
  • 43
  • 3
    FYI, what you have there is an array of objects, not JSON. [JSON](http://www.json.org/) is a specified data format. – Mike Cluck Mar 16 '16 at 22:52
  • 1
    There is no built in method for such a specific scenario. You will have to write the logic yourself. Or maybe [lodash](https://lodash.com/) may have some method that could help you. Don't know, I don't use lodash. – Dimitris Karagiannis Mar 16 '16 at 22:53
  • There's no built in way, but you can set create a custom sort function in JavaScript and use it on the array of objects (perhaps the `airplanes` array) you're looking to sort within the object. Here's an example of custom sorting: http://stackoverflow.com/questions/5002848/how-to-define-custom-sort-function-in-javascript – Anton Mar 16 '16 at 22:56

2 Answers2

3

Both Underscore and LoDash have a sort method that will do what you're looking for. In this example I am assuming that you have the data structure you showed stored in a variable called data.

 _.each(data, function(obj) {
     _.each(obj.row, function(row) {
        // note the reassignment, _.sortBy does not sort in-place
        row.airplanes = _.sortBy(row.airplanes, function(airplane) {
           return airplane.wid; // This will sort ascending. 
                                // To sort descending, simply multiply by -1
        });
     });
 });

So what is this doing? It's taking each array element in your root data structure and looping over it (that's the first _.each). Then in each of those objects, it is looping over each row element and sorting row.airplanes array by the wid element contained in each.

Hopefully this helps you. As an aside, that data you posted is strictly invalid JSON. Each key should be double quoted, i.e., "row", instead of just row and single quotes are invalid for delimiting strings, i.e., "DVD" instead of 'DVD'. Also, your boat version is a string whereas your other version identifiers are integers, it's a good idea to try and keep your version identifiers as integers.

daniel0mullins
  • 1,937
  • 5
  • 21
  • 45
  • I tried what you suggested at https://jsfiddle.net/z50rc770/ for some reason, it is not sorting the returned results (see the console output). I did a console.log(row.airplanes); was that not what I was supposed to do? I assumed row.airplanes would return the proper output? or would it automatically update the "data" array? – adbarads Mar 17 '16 at 05:03
  • 1
    I figured out my problem, I was adding both lodash.js and underscore.js cdns into my jsfiddle. Based on your answer, I thought I would have needed both. After realizing it's one or the other. I removed underscore.js and changed the _.each to _.forEach and now it appears to work as expected. Thanks for pointing me in the right direction. – adbarads Mar 17 '16 at 15:28
  • @adbarads Edited answer to make that clearer, thanks – daniel0mullins Mar 17 '16 at 22:25
  • @adbarads Also, many lodash functions have aliases (to provide drop-in replacement functionality for Underscore.js) so _.each and _.forEach are the same function. https://lodash.com/docs#forEach – daniel0mullins Mar 17 '16 at 22:28
0

I recommend using the excellent jq commandline JSON processor. Extremely fast since it was written in portable C. Easy to understand documentation.

cat <file.json> | jq . -S
Sandeep
  • 28,307
  • 3
  • 32
  • 24