如何对Javascript对象进行排序,或将其转换为数组?
我有一些从服务器获取的JSON数据。在我的JavaScript中,我想对它进行排序。我认为sort()函数可以满足我的要求 然而,JavaScript似乎正在将JSON数据在到达时立即转换为对象。如果我尝试使用sort()方法,就会出现大量错误(使用Firebug进行测试) 我环顾了一下网络,每个人似乎都在说,首先,JSON对象已经是JavaScript数组了,而且对象可以像数组一样处理。就像上一页一样,在其中一个答案中,一个人说:“对象是你的数据——你可以像访问数组一样访问它。” 然而,事实并非如此。JavaScript不允许我在对象上使用sort()。由于默认的假设是它们都是相同的东西,因此似乎没有任何关于如何将对象转换为数组,或强制JavaScript将其视为一个数组,或诸如此类的指令 所以。。。如何让JavaScript将此数据作为数组处理并对其进行排序 我的对象的控制台日志输出如下所示(我希望能够按照“级别”中的值进行排序): 对象JSONdata如何对Javascript对象进行排序,或将其转换为数组?,javascript,arrays,json,sorting,object,Javascript,Arrays,Json,Sorting,Object,我有一些从服务器获取的JSON数据。在我的JavaScript中,我想对它进行排序。我认为sort()函数可以满足我的要求 然而,JavaScript似乎正在将JSON数据在到达时立即转换为对象。如果我尝试使用sort()方法,就会出现大量错误(使用Firebug进行测试) 我环顾了一下网络,每个人似乎都在说,首先,JSON对象已经是JavaScript数组了,而且对象可以像数组一样处理。就像上一页一样,在其中一个答案中,一个人说:“对象是你的数据——你可以像访问数组一样访问它。” 然而,事实并
{
1: {
displayName: "Dude1",
email: "dude1@example.com<mailto:dude1@example.com>",
lastActive: 1296980700,
level: 57,
timeout: 12969932837
}, 2: {
displayName: "Dude2",
email: "dude2@example.com<mailto:dude2@example.com>",
lastActive: 1296983456,
level: 28,
timeout: 12969937382
}, 3: {
displayName: "Dude3",
email: "dude3@example.com<mailto:dude3@example.com>",
lastActive: 1296980749,
level: 99,
timeout: 129699323459
}
}
{
1: {
显示名称:“Dude1”,
电子邮件:“dude1@example.com",
最后激活:1296980700,
级别:57,
超时:12969932837
}, 2: {
显示名称:“Dude2”,
电子邮件:“dude2@example.com",
最新激活日期:1296983456,
级别:28,
超时:12969937382
}, 3: {
显示名称:“Dude3”,
电子邮件:“dude3@example.com",
最后激活:1296980749,
级别:99,
超时:129699323459
}
}
Array.prototype.slice.call(arrayLikeObject)
是将与数组类似的对象转换为数组的标准方法
这只适用于参数
对象。将泛型对象转换为数组有点麻烦。以下是来源:
事实证明,您需要在对象上循环并自己将其映射到数组
var newArray = []
for (var key in object) {
newArray.push(key);
}
你混淆了数组和“关联数组”的概念。在JavaScript中,对象的行为类似于关联数组,因为您可以访问object[“key”]
格式的数据。它们不是真正的关联数组,因为对象是无序列表
对象和数组大不相同
使用下划线的示例:
var sortedObject = _.sortBy(object, function(val, key, object) {
// return an number to index it by. then it is sorted from smallest to largest number
return val;
});
请参见您应该能够将JavaScript对象转换为如下所示的数组
var obj = {
'1': 'a',
'2': 'b',
'3': 'c'
};
var arr = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
arr.push(obj[key]);
}
}
console.log(arr); // ["a", "b", "c"]
。例如:
// Sorts the given objet in-place as if it was an array
Array.prototype.sort.call(yourObject);
因此,如果知道要排序的条目数(),可以执行以下操作:
yourObject.length = theNumberOfEntries;
Array.prototype.sort.call(yourObject);
// Optionally: delete yourObject.length;
请注意,这将仅对按“0”、“1”、“2”索引的属性进行排序。。。到
长度-1
包括在内,就像在数组中一样。对象的其他属性将不会被重新排序。我最近在尝试按其属性之一对对象数组进行分组时遇到了这个问题,导致一个对象无法排序
具体地说,这是一系列我想按年份分组并按年份递减排序的博客文章。我使用了下划线的实用程序:
var grouped = _.groupBy(blogposts, function(post){
var date = new Date(post.publication_date)
return date.getFullYear()
})
//=> { 2010: [blogpost, blogpost,etc], 2011: [blogpost, etc] }
正如@Raynos解释的那样,在排序之前,我必须先得到某种数组
事实证明,下划线(1.4)有一个很好的小实用程序,名为pairs
,它将在[key,value]数组中映射对象的{key:value}。相当于:
var paired = _.map(grouped, function(val, key){
return [key, val]
})
//=> [ [2010, [blogpost, blogpost, ...] ], [2011, [blogpost, blogpost, ...]]...]
从那以后,你可以很容易地按每对中的第一项进行排序
以下是最终结果:
var grouped = _.groupBy(result.resource, function(resource){
var date = new Date(resource.pub_date)
return date.getFullYear() //+ "." + (date.getMonth()+1)
})
var paired = _.pairs(grouped)
var sorted = _.sortBy(paired, function(pairs){
return -parseInt(pairs[0])
})
return sorted;
// Giving me the expected result:
//=> [ [2013, [blogpost, blogpost, ...] ], [2012, [blogpost, blogpost, ...]]...]
我确信有一种更好、更高效的方法,但是来自ruby的这段代码对我来说是可以理解的。jQuery提供了一个映射函数,它将迭代数组或对象中的每个元素,并将结果映射到一个新数组中 在jQuery 1.6之前,$.map()只支持遍历数组 我们可以使用它将任何对象转换为数组,如下所示
myArray = $.map(myObject, function (el) {
return el;
});
但是。。。
如果回调函数返回null或undefined,则该值将从数组中删除,在大多数情况下这是有用的,但如果在myArray中需要null值,则可能会导致问题
jQuery为此提供了一个解决方案。。。
将该值作为带有单个值的数组返回
myArrayWithNulls = jQuery.map(myObject, function (el) {
return [el];
});
这里有一把小提琴演示了两种方法:
我编写了一个小函数,用于递归地将具有属性的对象(也可能是对象)转换为多维数组。此代码依赖于forEach和toArray方法的下划线或lodash
function deepToArray(obj) {
var copy = [];
var i = 0;
if (obj.constructor == Object ||
obj.constructor == Array) {
_.forEach(obj, process);
} else {
copy = obj;
}
function process(current, index, collection) {
var processed = null;
if (current.constructor != Object &&
current.constructor != Array) {
processed = current;
} else {
processed = deepToArray(_.toArray(current));
}
copy.push(processed);
}
return copy;
}
这是小提琴:
注意:编写此命令的目的是将原来是数组的对象转换回数组,因此任何非数组索引键值都将丢失。大多数答案都会使问题过于复杂,或者使用JQuery或下划线,而OP从未要求这些 可以将对象转换为如下所示的数组:
myArray= Object.keys(data).map(function(key) { return data[key] });
myArray.sort(function(x, y) {return x.level - y.level});
并对结果进行如下排序:
myArray= Object.keys(data).map(function(key) { return data[key] });
myArray.sort(function(x, y) {return x.level - y.level});
如果需要id/索引,则需要做更多的工作:
Object.keys(data).map(function(key) {
var obj = data[key];
obj.index = key;
return obj
});
好的,是这样做的,但如果我将数组的结果回显到控制台中,它似乎是空的。只有两个方括号。[]@user184108您能为您的对象发布
console.log()
的输出吗?@alex尝试传入一个对象{“1”:1}。Array.prototype.slice.call仅对参数有效object@Raynos我懂了。我想下一步应该是显式循环并一次添加一个?@alex这就是下划线.js。我怀疑是否有更好的方法。我可以用Javascript对关联数组排序吗?假设键中的值是可排序的(键名是文本,但值是数字。)@user184108否。这没有本地的类型。看看Underline.js,它实现了像use和und这样的功能