Сортировка JSON по значениям - PullRequest
58 голосов
/ 19 мая 2009

У меня есть очень простой объект JSON, подобный следующему:

{
   "people":[
      {
         "f_name":"john",
         "l_name":"doe",
         "sequence":"0",
         "title":"president",
         "url":"google.com",
         "color":"333333"
      },
      {
         "f_name":"michael",
         "l_name":"goodyear",
         "sequence":"0",
         "title":"general manager",
         "url":"google.com",
         "color":"333333"
      }
   ]
}

Теперь, когда это возвращается из моего серверного кода, я запускаю jQuery.each, чтобы сформировать необходимый HTML и вывести результат.

Прямо сейчас я отправляю вызов AJAX на сервер, содержащий информацию о моей сортировке ... например, «Заголовок DESC» и повторите SQL-запрос, чтобы вернуть новый набор результатов. Но я хочу избежать этого и использовать jQuery для сортировки результирующего JSON, чтобы не допустить повторных обращений к серверу и множественного доступа к базе данных.

Как мне добиться этого с помощью jQuery?

Ответы [ 6 ]

116 голосов
/ 08 февраля 2012

jQuery не особенно полезен для сортировки, но вот элегантное и эффективное решение. Просто напишите простую функцию JS, которая берет имя свойства и порядок (возрастающий или убывающий) и вызывает собственный метод sort () с простой функцией сравнения:

var people = [
    {
        "f_name": "john",
        "l_name": "doe",
        "sequence": "0",
        "title" : "president",
        "url" : "google.com",
        "color" : "333333",
    }
    // etc
];

function sortResults(prop, asc) {
    people.sort(function(a, b) {
        if (asc) {
            return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
        } else {
            return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
        }
    });
    renderResults();
}

Тогда:

sortResults('l_name', true);

Играть с рабочим примером здесь .

21 голосов
/ 19 февраля 2013

Демо: http://jsfiddle.net/VAKrE/1019/

Успешно передать равные значения (сохранить тот же порядок). Гибкость: обрабатывать восходящий (123) или потомковый (321), работает с числами, буквами и юникодами. Работает на всех протестированных устройствах (Chrome, браузер Android по умолчанию, FF).

Приведенные данные такие :

var people = [ 
{ 'myKey': 'A', 'status': 0 },
{ 'myKey': 'B', 'status': 3 },
{ 'myKey': 'C', 'status': 3 },
{ 'myKey': 'D', 'status': 2 },
{ 'myKey': 'E', 'status': 7 },
...
];

Сортировка по возрастанию или в обратном порядке :

function sortJSON(data, key, way) {
    return data.sort(function(a, b) {
        var x = a[key]; var y = b[key];
        if (way === '123' ) { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }
        if (way === '321') { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); }
    });
}

people2 = sortJSON(people,'status', '321'); // 123 or 321
alert("2. After processing (0 to x if 123; x to 0 if 321): "+JSON.stringify(people2));
12 голосов
/ 19 мая 2009
jQuery.fn.sort = function() {  
    return this.pushStack( [].sort.apply( this, arguments ), []);  
};  

 function sortLastName(a,b){  
     if (a.l_name == b.l_name){
       return 0;
     }
     return a.l_name> b.l_name ? 1 : -1;  
 };  
  function sortLastNameDesc(a,b){  
     return sortLastName(a,b) * -1;  
 };
var people= [
{
"f_name": "john",
"l_name": "doe",
"sequence": "0",
"title" : "president",
"url" : "google.com",
"color" : "333333",
},
{
"f_name": "michael",
"l_name": "goodyear",
"sequence": "0",
"title" : "general manager",
"url" : "google.com",
"color" : "333333",
}]

sorted=$(people).sort(sortLastNameDesc);  
7 голосов
/ 02 декабря 2014

Если вы не возражаете против использования внешней библиотеки, Lodash имеет множество замечательных утилит

var people = [
  {
     "f_name":"john",
     "l_name":"doe",
     "sequence":"0",
     "title":"president",
     "url":"google.com",
     "color":"333333"
  },
  {
     "f_name":"michael",
     "l_name":"goodyear",
     "sequence":"0",
     "title":"general manager",
     "url":"google.com",
     "color":"333333"
  }
];


var sorted = _.sortBy(people, "l_name")

Вы также можете сортировать по нескольким свойствам. Вот план, показывающий это в действии

1 голос
/ 16 ноября 2015

Решение, работающее с различными типами и с верхним и нижним регистром.
Например, без оператора toLowerCase «Goodyear» будет стоять перед «doe» с восходящей сортировкой. Запустите фрагмент кода в нижней части моего ответа, чтобы просмотреть различные варианты поведения.

JSON DATA:

var people = [
{
    "f_name" : "john",
    "l_name" : "doe", // lower case
    "sequence": 0 // int
},
{
    "f_name" : "michael",
    "l_name" : "Goodyear", // upper case
    "sequence" : 1 // int
}];

Функция сортировки JSON:

function sortJson(element, prop, propType, asc) {
  switch (propType) {
    case "int":
      element = element.sort(function (a, b) {
        if (asc) {
          return (parseInt(a[prop]) > parseInt(b[prop])) ? 1 : ((parseInt(a[prop]) < parseInt(b[prop])) ? -1 : 0);
        } else {
          return (parseInt(b[prop]) > parseInt(a[prop])) ? 1 : ((parseInt(b[prop]) < parseInt(a[prop])) ? -1 : 0);
        }
      });
      break;
    default:
      element = element.sort(function (a, b) {
        if (asc) {
          return (a[prop].toLowerCase() > b[prop].toLowerCase()) ? 1 : ((a[prop].toLowerCase() < b[prop].toLowerCase()) ? -1 : 0);
        } else {
          return (b[prop].toLowerCase() > a[prop].toLowerCase()) ? 1 : ((b[prop].toLowerCase() < a[prop].toLowerCase()) ? -1 : 0);
        }
      });
  }
}

Использование:

sortJson(people , "l_name", "string", true);
sortJson(people , "sequence", "int", true);

var people = [{
  "f_name": "john",
  "l_name": "doe",
  "sequence": 0
}, {
  "f_name": "michael",
  "l_name": "Goodyear",
  "sequence": 1
}, {
  "f_name": "bill",
  "l_name": "Johnson",
  "sequence": 4
}, {
  "f_name": "will",
  "l_name": "malone",
  "sequence": 2
}, {
  "f_name": "tim",
  "l_name": "Allen",
  "sequence": 3
}];

function sortJsonLcase(element, prop, asc) {
  element = element.sort(function(a, b) {
    if (asc) {
      return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
    } else {
      return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
    }
  });
}

function sortJson(element, prop, propType, asc) {
  switch (propType) {
    case "int":
      element = element.sort(function(a, b) {
        if (asc) {
          return (parseInt(a[prop]) > parseInt(b[prop])) ? 1 : ((parseInt(a[prop]) < parseInt(b[prop])) ? -1 : 0);
        } else {
          return (parseInt(b[prop]) > parseInt(a[prop])) ? 1 : ((parseInt(b[prop]) < parseInt(a[prop])) ? -1 : 0);
        }
      });
      break;
    default:
      element = element.sort(function(a, b) {
        if (asc) {
          return (a[prop].toLowerCase() > b[prop].toLowerCase()) ? 1 : ((a[prop].toLowerCase() < b[prop].toLowerCase()) ? -1 : 0);
        } else {
          return (b[prop].toLowerCase() > a[prop].toLowerCase()) ? 1 : ((b[prop].toLowerCase() < a[prop].toLowerCase()) ? -1 : 0);
        }
      });
  }
}

function sortJsonString() {
  sortJson(people, 'l_name', 'string', $("#chkAscString").prop("checked"));
  display();
}

function sortJsonInt() {
  sortJson(people, 'sequence', 'int', $("#chkAscInt").prop("checked"));
  display();
}

function sortJsonUL() {
  sortJsonLcase(people, 'l_name', $('#chkAsc').prop('checked'));
  display();
}

function display() {
  $("#data").empty();
  $(people).each(function() {
    $("#data").append("<div class='people'>" + this.l_name + "</div><div class='people'>" + this.f_name + "</div><div class='people'>" + this.sequence + "</div><br />");
  });
}
body {
  font-family: Arial;
}
.people {
  display: inline-block;
  width: 100px;
  border: 1px dotted black;
  padding: 5px;
  margin: 5px;
}
.buttons {
  border: 1px solid black;
  padding: 5px;
  margin: 5px;
  float: left;
  width: 20%;
}
ul {
  margin: 5px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons" style="background-color: rgba(240, 255, 189, 1);">
  Sort the JSON array <strong style="color: red;">with</strong> toLowerCase:
  <ul>
    <li>Type: string</li>
    <li>Property: lastname</li>
  </ul>
  <button onclick="sortJsonString(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAscString" type="checkbox" checked="checked" />
</div>
<div class="buttons" style="background-color: rgba(255, 214, 215, 1);">
  Sort the JSON array <strong style="color: red;">without</strong> toLowerCase:
  <ul>
    <li>Type: string</li>
    <li>Property: lastname</li>
  </ul>
  <button onclick="sortJsonUL(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAsc" type="checkbox" checked="checked" />
</div>
<div class="buttons" style="background-color: rgba(240, 255, 189, 1);">
  Sort the JSON array:
  <ul>
    <li>Type: int</li>
    <li>Property: sequence</li>
  </ul>
  <button onclick="sortJsonInt(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAscInt" type="checkbox" checked="checked" />
</div>
<br />
<br />
<div id="data" style="float: left; border: 1px solid black; width: 60%; margin: 5px;">Data</div>
0 голосов
/ 05 марта 2014

Вот метод многоуровневой сортировки. Я включил фрагмент из модуля Angular JS, но вы можете сделать то же самое, определяя объекты ключей сортировки так, чтобы ваша функция сортировки имела к ним доступ. Вы можете увидеть полный модуль на Плункер .

$scope.sortMyData = function (a, b)
{
  var retVal = 0, key;
  for (var i = 0; i < $scope.sortKeys.length; i++)
  {
    if (retVal !== 0)
    {
      break;
    }
    else
    {
      key = $scope.sortKeys[i];
      if ('asc' === key.direction)
      {
        retVal = (a[key.field] < b[key.field]) ? -1 : (a[key.field] > b[key.field]) ? 1 : 0;
      }
      else
      {
        retVal = (a[key.field] < b[key.field]) ? 1 : (a[key.field] > b[key.field]) ? -1 : 0;
      }
    }
  }
  return retVal;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...