Сортировать Nested Json Объект по значению для l oop? - PullRequest
0 голосов
/ 06 марта 2020

Надеясь, что кто-то может помочь мне здесь или, по крайней мере, указать мне правильное направление. Я часами пытался разобраться в этом, и я потерян.

Приведенный ниже код просто ложный, мой фактический json возвращается через AJAX с использованием jquery. Моя проблема не в сортировке, а в сортировке вложенного объекта json.

Я пытаюсь отсортировать вывод json по стоимости. (от самой низкой цены до самой высокой), мои попытки не увенчались успехом, и я не могу отсортировать их Я продолжаю получать "сортировка" не определена.

Любая помощь будет признательна, или если вы можете просто указать, что я делаю здесь неправильно.

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>

Ответы [ 5 ]

2 голосов
/ 06 марта 2020

Преобразовать объект в отсортированный массив

Объект может быть расплющен так, что родительские ключи включаются в глубокий объект, поскольку он повторяется. Ранний пример тому можно найти в этой истории редактирования ответов. Он был удален, поскольку информация, подобная кавычке, не считалась важной.

Ниже приведен пример использования Object.values, который пересекает объект и возвращает только массив значений этого объекта (отбрасывая ключи). Значения могут быть отсортированы по назначению по cost.

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>

Котировки по стоимости за способ доставки

Предполагается, что необходим идентификатор котировки (возможно, для размещения в строке) ; в противном случае это можно упростить, используя Object.values вместо Object.entries (среди прочих изменений).

Не обращайте внимания на то, что делает функция output. Это быстрый пример, который не обеспечивает правильного порядка ячеек и имеет множество других ограничений и уязвимостей. Он используется только для демонстрации того, что исходные данные quote по-прежнему доступны после сортировки.

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>
1 голос
/ 06 марта 2020

Ваши объекты могут иметь любое количество свойств, и вы можете выбрать сортировку по любому желаемому свойству объекта, номеру или строке, если вы поместите объекты в массив.

var item = JSON.parse(json).shipping_method.ups.quote;

Использование Object.values ​​() , чтобы получить массив значений объекта JSON, а затем использовать метод slice () , чтобы скопировать массив объектов JSON, а не просто сделать ссылку.

var byCost = Object.values(item).slice(0);

Наконец, вы можете использовать функцию сортировки для этого массива объектов.

byCost.sort(function(a,b) {return a.cost - b.cost});

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":""}}}';
var item = JSON.parse(json).shipping_method.ups.quote;
var byCost = Object.values(item).slice(0);
byCost.sort(function(a,b) {return a.cost - b.cost});
console.log(byCost)
0 голосов
/ 06 марта 2020

Как я вижу, ваша проблема в том, чтобы отсортировать объект по стоимости, так как их ключи должны остаться прежними,

Попробуйте это,

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":""}}}';

var json = JSON.parse(json);
let data = []
for(var i in json.shipping_method.ups.quote){
    data.push(json.shipping_method.ups.quote[i])
    data.sort((a,b) => a.cost - b.cost);
}

Это создаст эти ключи снова, так как они до

let final = {} ;
data.forEach(el => final[el.code.split('.')[1]] = el);

Наконец, обновите qoute последними отсортированными цитатами:

json.shipping_method.ups.quote = final;
0 голосов
/ 06 марта 2020

вы можете попробовать следующее:

json = JSON.parse(json);
  let item = json.shipping_method.ups.quote,
    temp = [];
  for (let key in item) {
    temp.push(item[key]);
  }
  temp.sort((x, y) => x.cost - y.cost);
  json.shipping_method.ups.quote = temp;

преобразовать ваш объект в массив и затем отсортировать;

0 голосов
/ 06 марта 2020

Не похоже, что вы получаете правильный путь здесь ... Глядя на JSON, который вы опубликовали, вы должны попытаться отсортировать shipping_method.ups.quote, также стоит отметить, что shipping_method.ups.quote является объектом и должно быть преобразован в массив для вызова .sort , поскольку этот метод живет на прототипе массива.

Это можно сделать несколькими способами, но Object.values ​​() - это один таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...