按字母顺序对JSON进行排序

10

我有一个基于存储在表格中的数据生成的JSON对象。我需要能够以不同的方式对其进行排序,但是当我执行JSON.stringify(array)并尝试从那里进行排序时它不起作用。当我尝试仅执行array.sort();时,它会更改顺序,但最终并不起作用。我对JSON及其操作没有太多经验,因此我不知道还能尝试什么。在排序后,我需要遍历表格并以字母顺序重写所选类别。

JSON对象如下所示:

var arr = [{
"Functional Category":"T-Shirt",
"Brand Name":"threadless",
"When Obtained":"Last 3 Months",
"How Obtained":"Purchased",
"How Often Worn":"Monthly",
"Where It's Made":"India",
"Has a Graphic":"Yes"}]

我在这里设置了一个fiddle:http://jsfiddle.net/Skooljester/88HVZ/1/,我已经尝试了这里建议的方法但无法使其正常工作。

我的两个问题是:一、如何完成这个任务;二、是否有更好的排序方法?


5
下次请在问题中包含相关代码。如果 jsFiddle 崩溃(有时会发生),你的问题就是不完整的。 - Matt Ball
7个回答

8
首先,定义一个比较函数:
function compare(el1, el2, index) {
  return el1[index] == el2[index] ? 0 : (el1[index] < el2[index] ? -1 : 1);
}

接下来,要根据第一列对数组进行排序,请使用以下代码:

array.sort(function(el1,el2){
  return compare(el1, el2, "Functional Category")
});

或者,如果第一列相等,则按第一列从A到Z排序,并按第二列从Z到A排序:

array.sort(function(el1,el2){
  var compared = compare(el1, el2, "Functional Category")
  return compared == 0 ? -compare(el1, el2, "Brand Name") : compared;
});

这个很好用。我遇到了一个打印的问题,但已经解决了。可以在这里看到:http://jsfiddle.net/Skooljester/agcUk/3/ 非常感谢! - ayyp
2
是的,我已经使用了你之前的jsfiddle来测试它,参见http://jsfiddle.net/88HVZ/7/。 - Bart

8
请看下面代码...
function sortObject(o) {
    var sorted = {},
    key, a = [];

    for (key in o) {
        if (o.hasOwnProperty(key)) {
                a.push(key);
        }
    }

    a.sort();

    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
}

这有帮助吗?

请原谅我的经验不足,但在尝试实现代码时,它并没有按预期工作 http://jsfiddle.net/Skooljester/WtDTD/1/ - ayyp
1
这将在V8中针对数字键出现错误:http://code.google.com/p/v8/issues/detail?id=164 - Paul Baumgart
@MANISH LANGA,+1 伟大的函数!在我看来,这将是正确的答案。 :-) - Ionică Bizău

6
Mozilla 开发者文档对 sort 函数有一个很好的解释。你可以将一个函数作为参数提供,告诉浏览器如何进行排序。

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort

以下是来自该链接的一些伪代码,已添加myArray.sort调用并删除了函数名称:

myArray.sort(function(a, b) {
  if (a is less than b by some ordering criterion)
     return -1;
  if (a is greater than b by the ordering criterion)
     return 1;
  // a must be equal to b
  return 0;
});

编辑:看起来你有一个单元素数组,其中元素是一个对象。对象是无序的。在排序之前,你必须将其转换为数组。尝试这样做(使用 Object.keys 和 Array.prototype.map 函数通过 augment.js 为旧浏览器添加):

var result = Object.keys(myArray[0]).sort().map(function(key) {
    return [key,myArray[0][key]];
});

这将为您提供一个排序的、嵌套的数组,形式如下:
[["Brand Name","threadless"],
 ["Function Category","T-Shirt"],
 ...
]

我已经看过了,但无法弄清如何实现。 - ayyp

2

这里可能会对你有所帮助:

function (obj) {
   var a = [],x;
   for(x in obj){ 
     if(obj.hasOwnProperty(x)){
         a.push([x,obj[x]]);
     }
   }
   a.sort(function(a,b){ return a[0]>b[0]?1:-1; })
   return a;
}

该函数将传入的对象转换为包含键值对的二维数组,并按照键名进行升序排序后返回该数组。

1
如果您的意图是允许用户动态排序表格,那么我的方法可能略有不同。
有很多jQuery表格排序插件。我用过这个:http://tablesorter.com/docs/,效果不错。
可以进行多列排序、默认排序、事件绑定等等...
这样,您就可以像以前一样构建您的表格,甚至在页面输出之前就可以进行排序。

这是正确的意图。然而,由于我仍在学习Javascript / jQuery,我正在尝试在不使用插件的情况下进行排序。 - ayyp

0

如果你想对 JSON 属性进行深度排序(其中属性值也是 JSON 对象),这可能对未来的某个人有所帮助。

function sortObject(o) {
    var sorted = {},
    key, a = [];

    for (key in o) {
        if (o.hasOwnProperty(key)) {
                a.push(key);
        }
    }

    a.sort();

    for (key = 0; key < a.length; key++) {
        if(typeof o[a[key]] === 'object'){
            sorted[a[key]] = sortObject(o[a[key]]);
        } else{
            sorted[a[key]] = o[a[key]];
        }
        
    }
    return sorted;
}

没有实际的例子,这不是一个非常有用的答案,顺便说一下,它与原来的问题几乎没有关系。其次,请注意对象键迭代没有保证的顺序,但请参见例如 https://dev59.com/jW035IYBdhLWcg3wQtsg#5525812。最后,请了解 Object.keysObject.entries。如果您必须对对象进行排序,则可以大大简化您的方法。 - Bart

-1

你也可以使用这种方法。在这里使用较少的变量来少写几行代码!

var newArr = [{}]; // just to matching pattern with Que variable here
Object.keys(arr[0]).sort().forEach(s => {
    newArr[0][s] = arr[0][s];
})

console.log(newArr);

输出:

[{
  "Brand Name": "threadless",
  "Functional Category": "T-Shirt",
  "Has a Graphic": "Yes",
  "How Obtained": "Purchased",
  "How Often Worn": "Monthly",
  "When Obtained": "Last 3 Months",
  "Where It's Made": "India"
}]

这只是将单个项目中的键排序(arr[0] 在此处是一个强烈的提示),而不是多个项目。此外,从另一个数组手动构造一个数组应该使用 .map,而不是.forEach,并将其转换为新数组。 - Bart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接