Sort Nested Json Object based on value in for loop?

limit :

Hoping someone can help me out here or at least point me in the right direction. I have spent hours trying to get this sorted and I am lost.

The code below is just mock, my actual json is returned via AJAX using jquery. My problem is not sorting, but sorting on a nested json object.

I am trying to sort the json output based on cost. (lowest cost to highest), my attempts have failed and I cannot get this sorted. I keep getting "sort" is undefined.

Any help would be appreciated or if you can just point out what I am doing wrong here.

var json = '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';

    /* 

    This doesnt work and returns undefined. 
    
    json["shipping_method"]["quote"].sort(function(a, b) {
        return a['cost'] > b['cost'];
      });

    // I found this example, but also didn't work.
    custSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {
    const a = prop2 ? e1[prop1][prop2] : e1[prop1],
    b = prop2 ? e2[prop1][prop2] : e2[prop1],
    sortOrder = direction === "asc" ? 1 : -1
     return (a < b) ? -sortOrder : (a > b) ? //sortOrder : 0;
    };      

   json.sort(custSort("quote", "cost", "desc"));*/


json = JSON.parse(json);

for (var i in json["shipping_method"]) {

  // EDIT::  I want the sorting to occur here if possible. 

  for (j in json["shipping_method"][i]["quote"]) {


  //EDIT::  I want to keep this for loop, but with the results sorted by cost 

    console.log(json["shipping_method"][i]["quote"][j]["cost"]);

  }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Mike :

Convert Object to Sorted Array

You might want to flatten out your object so you can refer to some of the metadata (like shipping method and quote) as done below. Then you can store that in an array and sort it as attempted.

const json = JSON.parse(getData());

for (let method in json["shipping_method"]) {
  // cache
  let quotes = json['shipping_method'][method]['quote']
  
  // convert object to array and sort
  let sortedQuotes = Object.values(quotes).sort((a, b)=>a.cost-b.cost);
  
  console.log(sortedQuotes)
}


/* Dummy Data */
function getData() {
  return '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';
}
.as-console-wrapper {
  max-height: 100vh !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Quotes by Cost per Shipping Method

This assumes that the quote ID is needed (perhaps to be placed on a row); otherwise this can be simplified using Object.values in place of Object.entries (amongst other changes).

Disregard what the output function is doing. It is a quick example, that doesn't ensure proper cell order and has a host of other limitations and vulnerabilities. It is only used to demonstrate that the original quote data is still available after sorting.

const data = JSON.parse(getData());

for (let method in data.shipping_method) {
  output({row: method}, {class:'capitalize'})
  
  // cache
  let quotes = data.shipping_method[method].quote
  let sortContent = Object.entries(quotes);
  let sortedQuotes = sortContent.sort((a,b)=>a[1].cost-b[1].cost).map(i=>i[0]);
  
  for (let quoteId of sortedQuotes){
    let quoteInfo = quotes[quoteId];
    output({cell: quoteInfo})
  }
}

/* Dummy Data */
function getData() {
  return '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';
}

/* Really simple output for demo purpose */
function output(data, options={}){

  if ('row' in data){
    let $col = $('<td></td>', options).html(data.row)
    let $row = $('<tr></tr>').append($col);
    $('tbody').append( $row )
  }
  
  else if ('cell' in data){
    let $row = $('<tr></tr>')
    for( let key in data.cell ){
      let $col = $('<td></td>', options).html(data.cell[key])
      $row.append($col)
    }
    $('tbody').append( $row )
  }
  
}
.capitalize {
  text-transform: uppercase;
}

td {
  min-width: 5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table>
  <thead></thead>
  <tbody></tbody>
</table>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=31978&siteId=1