排序 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】:
查看JSONArray
s。他们可能是你需要的。 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 对象的主要内容,如果未能解决你的问题,请参考以下文章