排序 JSON 对象

Posted

技术标签:

【中文标题】排序 JSON 对象【英文标题】:Sorting JSON Object 【发布时间】:2011-09-03 02:28:18 【问题描述】:

尝试对 JSON 对象进行排序时遇到问题。基本上,人们可以以任何随机顺序将产品添加到我们的订单中,但它在摘要中显示的顺序需要是我们希望它们的位置(而不是他们选择它们的顺序),所以这就是我需要排序的原因'id'(或者我们稍后会按 'pos' 字段排序)

基本上,我需要按 id 升序排序。 1,2,103 而不是 2,103,1

我似乎遇到了问题,因为单个对象的索引是数字(或者只是它们存在的事实......)。

我需要按照 array.sort(function(a,b) return a.id-b.id );但我认为这不起作用,因为 1,它不是一个数组(它是一个对象),而 2,它有那些讨厌的索引(我需​​要我的代码的另一部分)......

有什么想法吗????

var products = 
    "2": 
        "id": "2",
        "price": "119",
        "quantity": "1",
        "thumb": "img\/store\/comp-08n.png"
    ,
    "103": 
        "id": "103",
        "price": "109",
        "quantity": "1",
        "thumb": "img\/store\/basketballhoop.png"
    ,
    "1": 
        "id": "1",
        "price": "309",
        "quantity": "1",
        "thumb": "img\/store\/comp-08.png"
    
;

【问题讨论】:

对象本质上是无序的(即,属性包没有“排序”);你期望的结果是什么? 我认为他使用的是一个对象作为关联数组,而不是他真正想要的“稀疏数组”。 使用对象数组。此外,检查 underscore.js。挺好看的。 【参考方案1】:

您的订单需要多少件商品?您可以安全地对 javascript 数组中的 10'000 个项目进行排序,而不会出现很多速度问题。为什么不使用真正的数组呢?

您甚至可以向其注入自定义属性,大致类似于

var products = [...];

products.findById = function(id) 
   for (var i=0, len=this.length; i<len; i++) 
      if (id == this[i].id) return this[i];
   
   return null;
;

alert( products.findById(103).price );   // -> 119

并添加预定义的排序器,例如

products.sortById = function() 
    this.sort(function(a,b) 
        return a.id - b.id;
    );
;

products.sortById();   // sort array by product id

** 编辑 **

在你的 php 端,你可能有类似的东西:

$products = array(
    2 => array( 'id' => 2, ... ),
    103 => array( 'id' => 103, ... ),
    1 => array( 'id' => 1, ... ),
);

// get a JSON array
$jsonArray = json_encode(array_values($products));

将返回您需要的内容。

** 注意 **

在数组中添加新项目时,不应显式设置索引。使用数组的push函数,比如

products.push(id:123, price:200.49, quantity:1, thumb:'/path/to/file');

删除一个项目有点棘手,但是,类似于:

products.removeById = function(id) 
   for (var i=0, len=this.length; i<len; i++) 
      if (id == this[i].id) return this.splice(i, 1)[0];
   
   return null;
;

products.removeById(123);    // -> returns the removed element! or null if nothing was removed

查看演示 here(使用 Chrome 开发工具进行控制台输出)。

【讨论】:

最多可能有 20 个……嗯,PHP 是否具有将关联数组转储到 JS 数组中的功能,还是我只做一个?目前我只是在使用 json_encode php 有 json_encode() 如果所有索引都是整数,则返回一个 Javascript 数组(参见手册) 非常感谢 Yanick,非常有帮助 :) 我使用您的分拣机让它工作,并让 PHP 将其转储为对象数组而不是对象对象 很高兴我能帮上忙。查看最新的修改以了解更多详情(如果您还没有这样做) 再次感谢!我只是注意到 findBy 是我如何找到适当的索引而不是设置它(在大声笑之前没有下沉)。您是否会说在开始时将我的数组排序为正确的索引(使用 for products.length newarr[products[i].id] = products[i])之间的性能差异,以便我可以通过 product[id] 访问更好还是比每次更改产品时都运行 findById 函数更糟糕(速度方面)?【参考方案2】:

在 JavaScript 和 JSON 中有两种类型的集合:

    键/值映射(对象) - 无序集合和 数组 - 索引/值映射(数组) - 有序集合。

根据定义,只能对数组进行排序。使用数组。

【讨论】:

那么,例如,我如何在不知道输出顺序的情况下访问 id 的价格?例如我不能只做产品[1][1] 是价格或其他什么...:\ @Benno 你只会做 product[1].price 所以我的数组看起来像这样? var products = [1:price:109,name:'Thing'];因为这似乎不起作用.. 很奇怪,我之前从未创建过这样的数组,哈哈:\ @Benno,使用这个:var a = []; a[1] = price:109,name:'Thing'; 等。大多数 JS 实现使用所谓的稀疏数组,因此您可以创建带有“孔”的数组。 “稀疏数组”与使用对象完全一样。它的存储方式相同,处理方式相同,length 不再适合使用。那么你没有将数组用作数组。【参考方案3】:

递归解决方案,但不处理数组,javascript

var alphabetizeJSON = function(obj)
    var key,
        array = [],
        stringifiedValuesObj = ,
        jsonKeyVal = "",
        i,
        keyName;

    for (key in obj) 
        if (typeof obj[key] === "object")
            stringifiedValuesObj[key] = "" + alphabetizeJSON(obj[key]);
         else 
            obj[key] = obj[key].replace(/\"/gi,'\\\"');
        
        array.push(key);
    

    array.sort();

    for (i = 0; i < array.length; i++)
        keyName = array[i];
        jsonKeyVal += '"' + keyName + '": ';
        jsonKeyVal += stringifiedValuesObj[keyName] ? stringifiedValuesObj[keyName] : '"' + obj[keyName] + '"';
        if (i < array.length - 1 ) 
            jsonKeyVal += ',';
        
    

    return ' ' + jsonKeyVal + '';
;

【讨论】:

我收到以下错误:ReferenceError: orderJSON is not defined 谢谢,已修复。我更改了函数的名称【参考方案4】:

查看JSONArrays。他们可能是你需要的。 http://json.org/java/

【讨论】:

【参考方案5】:

确实,您应该能够使用数组而不是对象来完成这项工作,这将解决您的很多困难。

如果你不能这样做,你可以将对象转换成一个数组来给它排序......像这样:

var a = []
for (var p in obj) 
  a[+p] = obj[p]

如果你不能这样做,你可以按照你想要的顺序动态地将信息添加到页面中(以下是一个坏主意)......

for (var i = 0; i < 10000; i++) 
  if (obj[i] !== undefined) 
    add_to_page(obj[i])  //define this somewhere
  

【讨论】:

嗯,这确实有效,哈哈,赢了!虽然我意识到它会浪费资源(尽管它们是最小的),所以我会先尝试将它转换为数组,但如果我厌倦了,我会这样做:)

以上是关于排序 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

怎样在java代码里获取一个json对象,然后对其进行排序,排好了之后,再返回给json?

在 Javascript 中对 JSON 对象进行排序

C#:按值对 json 对象进行排序

对简单的 JSON 对象进行排序 [重复]

json对象数组按对象属性排序

如何按嵌套值对 JSON 对象进行排序?