[英]Sort an array of objects in Javascript by key value
First time poster, long time reader. 第一次海报,长时间阅读。 I'm having a problem sorting an array of objects, this is homework so I'm not asking for someone to write the code for me just point me in the right direction or show me my over sight.
我在排序一系列对象时遇到问题,这是家庭作业,所以我不是要求别人为我编写代码,只是指向正确的方向或向我展示我的视线。 The object is to write a function to sort an array of objects when passing in an array and a key ie:
对象是在传入数组和键时写一个函数来对对象数组进行排序,即:
([{a:2},{b:2},{a:1},{a:3},{b:3},{b:1}], “a”)
Should return 应该回来
[{a:1},{a:2},{a:3},{b:1},{b:2},{b:3}];
I can't use anything like underscore.js or node.js 我不能使用像underscore.js或node.js这样的东西
//example array to use
var testarr = [{a:2},{b:2},{a:1},{a:3},{b:3},{b:1}];
console.log("array sort test: should look like [{a:1},{a:2},{a:3},{b:1},{b:2},{b:3}]");
//first attempt
var sortArrayByKey = function (arr1, key) {
(arr1.sort(function(a,b){
return a[key] - b[key];}));
return arr1;
};
//still only returns testarr
console.log(sortArrayByKey(testarr, "a") );
//second attempt
var sortArrayByKey1 = function (array, key) {
var compareByKey = function (a, b) {
var x = a[key]; var y = b[key];
return x - y;
}
array.sort(compareByKey);
return array;
};
//still only returns testarr
console.log(sortArrayByKey1(testarr, “a”));
![pic of requirements in-case i'm describing it wrong photo ![我在描述错误照片的情况下的要求图片
Hmm.. this is a weird one. 嗯..这是一个奇怪的。 First you need to check if one of the keys is the priority key and sort based on that.
首先,您需要检查其中一个密钥是否为优先级密钥,并根据该密钥进行排序。 Then if both keys are equal sort by the values.
然后,如果两个键相等,则按值排序。 The problem is that there is no straightforward way to get the key but you can use the
for .. in
loop. 问题是没有直接的方法来获取密钥,但你可以使用
for .. in
循环。
I'm going to assume that each object contains only one property otherwise the code will not make sense since property is unordered in objects: 我将假设每个对象只包含一个属性,否则代码将没有意义,因为属性在对象中是无序的:
function sortPreferredKey(arr,key) {
arr.sort(function(a,b){
// get the keys of each object
for (var a_key in a) {break}
for (var b_key in b) {break}
if (a_key != b_key) {
if (a_key == key) return 1;
else if (b_key == key) return -1;
else return 0;
}
return a[a_key] - b[b_key];
});
}
I may have gotten the order of sort wrong but you get the idea. 我可能已经得到了错误的顺序,但你明白了。 It's really weird that you'd even need to do something like this.
你甚至需要做这样的事情真的很奇怪。
Here's my solution. 这是我的解决方案。 I made it so you can also add more keys and sort them too.
我做了它,所以你也可以添加更多的密钥并对它们进行排序。
Fiddle - http://jsfiddle.net/Q7Q9C/3/ 小提琴 - http://jsfiddle.net/Q7Q9C/3/
function specialSort(arrayToSort, keyOrder) {
arrayToSort = arrayToSort.sort(function (a, b) {
for (var key in keyOrder) {
if (!keyOrder.hasOwnProperty(key)) {
continue;
}
var aKey = keyOrder[key];
if (typeof a[aKey] === "undefined" && typeof b[aKey] === "undefined") {
continue;
}
if (typeof a[aKey] !== "undefined" && typeof b[aKey] === "undefined") {
return -1;
}
if (typeof a[aKey] === "undefined" && typeof b[aKey] !== "undefined") {
return 1;
}
if (a[aKey] > b[aKey]) {
return 1;
}
else if (a[aKey] < b[aKey]) {
return -1;
}
}
return 0;
});
return arrayToSort;
}
var arrayToSort = [
{a:2},
{b:2},
{a:1},
{a:3},
{b:3},
{c:3},
{c:2},
{b:1}
];
var keyOrder = ["a", "b", "c"];
var sortedArray = specialSort(arrayToSort, keyOrder);
console.log(JSON.stringify(sortedArray));
This is the best I can come up with. 这是我能想到的最好的。 It will sort all the elements with the given key to the front;
它将使用给定键对所有元素进行排序; the elements without the key will be in the back, but they'll be in an unpredictable order.
没有钥匙的元素将在后面,但它们将处于不可预测的顺序。
function sortArrayByKey(arr, key) {
function compareKey(a, b) {
if (a.hasOwnProperty(key)) {
if (b.hasOwnProperty(key)) {
return a[key] - b[key];
} else {
return -1;
}
} else if (b.hasOwnProperty(key)) {
return 1;
} else {
return 0;
}
}
arr.sort(compareKey);
return arr;
}
Here's a solution that makes a guess what to do if neither object being compared in the array has the passed in comparison key: 这是一个解决方案,如果数组中的比较对象都没有传入比较键,则可以猜测该怎么做:
var data = [{a:2},{b:2},{a:1},{a:3},{b:3},{b:1}];
function sortByProperty(array, propName) {
function findFirstProperty(obj) {
for (x in obj) {
if (obj.hasOwnProperty(x)) {
return x;
}
}
}
return array.sort(function(first, second) {
var firstHasProp = propName in first;
var secondHasProp = propName in second;
if (firstHasProp) {
if (secondHasProp) {
// both have the property
return first[propName] - second[propName];
} else {
// only first has the property
return -1;
}
} else if (secondHasProp){
// only second has the property
return 1;
} else {
// Neither sort candidate has the passed in property name
// It is not clear what you want to do here as no other property
// name has been specified
return first[findFirstProperty(first)] - second[findFirstProperty(second)]
}
});
}
Working demo: http://jsfiddle.net/jfriend00/PFurT/ 工作演示: http : //jsfiddle.net/jfriend00/PFurT/
Logically, here's what it does: 从逻辑上讲,这是它的作用:
Here's a version that works like the above one, but is has been extended to sort properties that are not the passed in property in alpha order and to deal with empty objects (with no properties) so they go at the end of the sort: 这是一个与上面的版本类似的版本,但是已经扩展为对按字母顺序不是传入属性的属性进行排序,并处理空对象(没有属性),因此它们在排序结束时进行:
var data = [{c:4},{a:2},{b:2},{a:1},{a:3},{b:3},{b:1},{},{c:3}];
function sortByProperty(array, propName) {
function findFirstProperty(obj) {
for (x in obj) {
if (obj.hasOwnProperty(x)) {
return x;
}
}
}
return array.sort(function(first, second) {
var firstHasProp = propName in first;
var secondHasProp = propName in second;
if (firstHasProp) {
if (secondHasProp) {
// both have the property
return first[propName] - second[propName];
} else {
// only first has the property
return -1;
}
} else if (secondHasProp){
// only second has the property
return 1;
} else {
// Neither sort candidate has the passed in property name
// It is not clear what you want to do here as no other property
// name has been specified
var firstProp = findFirstProperty(first);
var secondProp = findFirstProperty(second);
if (firstProp === undefined && secondProp === undefined) {
return 0;
} else if (firstProp === undefined) {
return 1;
} else if (secondProp === undefined) {
return -1;
}
else if (firstProp === secondProp) {
return first[firstProp] - second[secondProp];
} else {
return firstProp.localeCompare(secondProp);
}
}
});
}
Working demo: http://jsfiddle.net/jfriend00/6QsVv/ 工作演示: http : //jsfiddle.net/jfriend00/6QsVv/
The documentation for the sort method is here . sort方法的文档在这里 。 The compare function:
比较功能:
should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.
应该是一个接受两个参数x和y的函数,如果x <y则返回负值,如果x = y则返回零,如果x> y则返回正值。
The function is passed the values in the array, so it's like calling the function with: 该函数传递给数组中的值 ,因此就像调用函数一样:
compareFunction({a:2},{b:2});
What you seem to want to do is sort on the property name first, then on the value. 你似乎想要做的是首先对属性名称进行排序,然后对值进行排序。 The problem with that is that you can't guarantee what order the property names are returned in. In this case, if you have exactly one own property for each object, you can do:
问题是您无法保证返回属性名称的顺序。在这种情况下,如果每个对象只有一个属性,则可以执行以下操作:
// Return first own property returned by in
// ORDER IS NOT GUARANTEED
function getPropName(o) {
for (var p in o) {
if (o.hasOwnProperty(p)) {
return p;
}
}
}
function specialSort(array, key) {
array.sort(function (a, b) {
var aProp = getPropName(a);
var bProp = getPropName(b);
// If properties are the same, compare value
if (aProp == bProp) {
return a[aProp] - b[bProp];
}
// Otherwise, compare keys
return aProp == key? -1 : bProp == key? 1 : aProp.charCodeAt(0) - bProp.charCodeAt(0);
});
return array;
}
The above will also sort any other keys (c, d, e, etc.) after the preferred key so: 以上还将对首选键后的任何其他键(c,d,e等)进行排序,以便:
var a = [{c:3},{a:2},{b:2},{c:2},{a:1},{a:3},{b:3},{b:1},{c:1}]
specialSort(a, 'b'); // [{b:1}, {b:2}, {b:3}, {a:1}, {a:2}, {a:3}, {c:1}, {c:2}, {c:3}]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.