关于jquery:按值排序JSON

Sorting JSON by values

我有一个非常简单的JSON对象,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
  "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调用…例如,"title desc"并重新运行SQL查询以返回新的结果集。但我希望避免这种情况,并使用jquery对生成的JSON进行排序,以防止往返于服务器和多个数据库访问。

如何使用jquery实现这一点?


为了优雅和高效,试试这个。

jquery很好,但是它不适合在这里排序,除非您没有现成的原始数组。只需编写一个将属性名作为字符串,并将顺序(升序或降序)作为布尔值的函数,编写一个简单的比较函数,然后使用本机JS sort()函数。这样就不必为每个属性编写单独的排序函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var people = [
    {
       "f_name":"john",
       "l_name":"doe",
       "sequence":"0",
       "title" :"president",
       "url" :"google.com",
       "color" :"333333",
    }
    // etc
];

function sortResults(prop, asc) {
    people = 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);
        }
    });
    showResults();
}

然后:

1
sortResults('l_name', true);

在这里玩一个有效的例子。


演示:http://jsfiddle.net/vakre/1019/

成功传递相等的值(保持相同的顺序)。灵活:处理上升(123)或下降(321),适用于数字,字母和单码。适用于所有测试设备(Chrome、Android默认浏览器、FF)。

给定数据如下:

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

按升序或逆序排序:

1
2
3
4
5
6
7
8
9
10
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));


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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);


如果你不介意使用外部图书馆,罗达什有很多很棒的实用工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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")

还可以按多个属性排序。这是一个突袭行动


解决方案使用不同类型和大小写。
例如,如果没有toLowerCase语句,"goodyear"将以升序出现在"doe"之前。运行我答案底部的代码段,查看不同的行为。

JSON数据:

1
2
3
4
5
6
7
8
9
10
11
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排序函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);
        }
      });
  }
}

用途:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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("" + this.l_name +"" + this.f_name +"" + this.sequence +"<br />");
  });
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

  Sort the JSON array with 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" />


  Sort the JSON array without 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" />


  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" />

<br />
<br />
Data


这是一个多级排序方法。我包含了一个角度JS模块的片段,但是您可以通过确定排序键对象的范围来完成相同的事情,这样您的排序函数就可以访问这些对象。你可以在普朗克看到完整的模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$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;
};