Javascript 按属性按重要性顺序对JSON对象数组进行排序
我有一堆歌曲存储在JavaScript对象数组中。看起来是这样的:Javascript 按属性按重要性顺序对JSON对象数组进行排序,javascript,arrays,json,sorting,Javascript,Arrays,Json,Sorting,我有一堆歌曲存储在JavaScript对象数组中。看起来是这样的: var library = [ { "title": "40 Years Later", "album": "Tears of Steel", "year": 2012, "track": 1, "disk": 1, "time": 31 }, { "title": "The Dome", "album": "Tears of Steel", "year": 2012, "track": 2
var library = [
{ "title": "40 Years Later", "album": "Tears of Steel", "year": 2012, "track": 1, "disk": 1, "time": 31 },
{ "title": "The Dome", "album": "Tears of Steel", "year": 2012, "track": 2, "disk": 1, "time": 311 },
{ "title": "The Battle", "album": "Tears of Steel", "year": 2012, "track": 3, "disk": 1, "time": 123 },
{ "title": "End Credits", "album": "Tears of Steel", "year": 2012, "track": 4, "disk": 1, "time": 103 },
{ "title": "The Wires", "album": "Elephants Dream", "year": 2006, "track": 1, "disk": 1, "time": 75 },
{ "title": "Typewriter Dance", "album": "Elephants Dream", "year": 2006, "track": 2, "disk": 1, "time": 70 },
{ "title": "The Safest Place", "album": "Elephants Dream", "year": 2006, "track": 3, "disk": 1, "time": 45 },
{ "title": "Emo Creates", "album": "Elephants Dream", "year": 2006, "track": 4, "disk": 1, "time": 60 },
{ "title": "End Title", "album": "Elephants Dream", "year": 2006, "track": 5, "disk": 1, "time": 91 },
{ "title": "Teaser Music", "album": "Elephants Dream", "year": 2006, "track": 6, "disk": 1, "time": 75 },
{ "title": "Ambience", "album": "Elephants Dream", "year": 2006, "track": 7, "disk": 1, "time": 110 },
{ "title": "Snow Fight", "album": "Sintel", "year": 2010, "track": 1, "disk": 1, "time": 107 },
{ "title": "Finding Scales / Chicken Run", "album": "Sintel", "year": 2010, "track": 2, "disk": 1, "time": 107 },
{ "title": "The Ziggurat", "album": "Sintel", "year": 2010, "track": 3, "disk": 1, "time": 78 },
{ "title": "Expedition", "album": "Sintel", "year": 2010, "track": 4, "disk": 1, "time": 93 },
{ "title": "Dragon Blood Tree", "album": "Sintel", "year": 2010, "track": 5, "disk": 1, "time": 47 },
{ "title": "Cave Fight / Lament", "album": "Sintel", "year": 2010, "track": 6, "disk": 1, "time": 145 },
{ "title": "I Move On (Sintel's Song)", "album": "Sintel", "year": 2010, "track": 7, "disk": 1, "time": 169 },
{ "title": "Circling Dragons", "album": "Sintel", "year": 2010, "track": 8, "disk": 1, "time": 28 },
{ "title": "Trailer Music", "album": "Sintel", "year": 2010, "track": 9, "disk": 1, "time": 44 }
];
function priority(opt) {
if (!(opt instanceof Array)) {
opt = Array.prototype.slice.call(arguments);
}
return function (a, b) {
for (var i = 0; i < opt.length; ++i) {
var option = opt[i];
if (typeof option === 'string') {
option = [option, '+'];
}
if (option.length < 2) {
option[1] = '+';
}
if (a[option[0]] !== b[option[0]]) {
if (a[option[0]] === undefined) return 1;
if (b[option[0]] === undefined) return -1;
if (typeof a[option[0]] === 'string' || typeof b[option[0]] === 'string') {
return (option[1] === '+' ? String(a[option[0]]).toLowerCase() < String(b[option[0]]).toLowerCase() : String(a[option[0]]).toLowerCase() > String(b[option[0]]).toLowerCase()) ? -1 : 1;
} else {
return (option[1] === '+' ? a[option[0]] < b[option[0]] : a[option[0]] > b[option[0]]) ? -1 : 1;
}
}
}
return 0;
};
}
library.sort(priority(['album', 'disk', ['title', '-']])
library.sort(priority(['album', '-year', '+title']));
or
library.sort(priority('album', '-year', '+title'));
我需要按字母和数字顺序按属性排序。有很多关于StackOverflow的文章和问题涉及到按单个值排序,有些文章和问题似乎涉及多个值,但它们没有顺序或重要性
我需要按几个值对每个对象(歌曲)进行排序,其中每个值的重要性级别较低。例如:
专辑
名称(字母)>磁盘
编号(数字)>曲目
编号(数字)>标题
(字母)>等
这意味着相册是按字母顺序排列的。在每个唱片集中都有按唱片编号排序的歌曲,因此磁盘1中的所有歌曲都在顶部,然后磁盘2中的所有歌曲,等等。在每个唱片编号分组中,都是按曲目编号排序的歌曲。如果有多首歌曲具有相同的曲目编号,或者没有曲目编号,则将按歌曲标题按字母顺序进行排序。如果曲目标题也相同,则可以提供更多属性
大写不重要,它应该像正常的字母排序那样排序(如果它以数字开头,则在字母之前,特殊字符将像在传统排序中一样有它们的位置)
我尝试过使用这段代码(它有硬编码的排序值,并且没有磁盘号),但它只是按照代码中最内部的属性,track number进行排序
library.sort(function (a, b) {
if (a.album === b.album) {
if (a.track === b.track) {
var x = a.title.toLowerCase();
var y = b.title.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
}
var x = a.track;
var y = b.track;
return x < y ? -1 : x > y ? 1 : 0;
}
return a.album.toLowerCase() - b.album.toLowerCase();
});
单个值也应该能够按降序排序,可能看起来像
-album
或[“album”,true]
。语法是灵活的。您可以使用如下函数:
var library = [
{ "title": "40 Years Later", "album": "Tears of Steel", "year": 2012, "track": 1, "disk": 1, "time": 31 },
{ "title": "The Dome", "album": "Tears of Steel", "year": 2012, "track": 2, "disk": 1, "time": 311 },
{ "title": "The Battle", "album": "Tears of Steel", "year": 2012, "track": 3, "disk": 1, "time": 123 },
{ "title": "End Credits", "album": "Tears of Steel", "year": 2012, "track": 4, "disk": 1, "time": 103 },
{ "title": "The Wires", "album": "Elephants Dream", "year": 2006, "track": 1, "disk": 1, "time": 75 },
{ "title": "Typewriter Dance", "album": "Elephants Dream", "year": 2006, "track": 2, "disk": 1, "time": 70 },
{ "title": "The Safest Place", "album": "Elephants Dream", "year": 2006, "track": 3, "disk": 1, "time": 45 },
{ "title": "Emo Creates", "album": "Elephants Dream", "year": 2006, "track": 4, "disk": 1, "time": 60 },
{ "title": "End Title", "album": "Elephants Dream", "year": 2006, "track": 5, "disk": 1, "time": 91 },
{ "title": "Teaser Music", "album": "Elephants Dream", "year": 2006, "track": 6, "disk": 1, "time": 75 },
{ "title": "Ambience", "album": "Elephants Dream", "year": 2006, "track": 7, "disk": 1, "time": 110 },
{ "title": "Snow Fight", "album": "Sintel", "year": 2010, "track": 1, "disk": 1, "time": 107 },
{ "title": "Finding Scales / Chicken Run", "album": "Sintel", "year": 2010, "track": 2, "disk": 1, "time": 107 },
{ "title": "The Ziggurat", "album": "Sintel", "year": 2010, "track": 3, "disk": 1, "time": 78 },
{ "title": "Expedition", "album": "Sintel", "year": 2010, "track": 4, "disk": 1, "time": 93 },
{ "title": "Dragon Blood Tree", "album": "Sintel", "year": 2010, "track": 5, "disk": 1, "time": 47 },
{ "title": "Cave Fight / Lament", "album": "Sintel", "year": 2010, "track": 6, "disk": 1, "time": 145 },
{ "title": "I Move On (Sintel's Song)", "album": "Sintel", "year": 2010, "track": 7, "disk": 1, "time": 169 },
{ "title": "Circling Dragons", "album": "Sintel", "year": 2010, "track": 8, "disk": 1, "time": 28 },
{ "title": "Trailer Music", "album": "Sintel", "year": 2010, "track": 9, "disk": 1, "time": 44 }
];
function priority(opt) {
if (!(opt instanceof Array)) {
opt = Array.prototype.slice.call(arguments);
}
return function (a, b) {
for (var i = 0; i < opt.length; ++i) {
var option = opt[i];
if (typeof option === 'string') {
option = [option, '+'];
}
if (option.length < 2) {
option[1] = '+';
}
if (a[option[0]] !== b[option[0]]) {
if (a[option[0]] === undefined) return 1;
if (b[option[0]] === undefined) return -1;
if (typeof a[option[0]] === 'string' || typeof b[option[0]] === 'string') {
return (option[1] === '+' ? String(a[option[0]]).toLowerCase() < String(b[option[0]]).toLowerCase() : String(a[option[0]]).toLowerCase() > String(b[option[0]]).toLowerCase()) ? -1 : 1;
} else {
return (option[1] === '+' ? a[option[0]] < b[option[0]] : a[option[0]] > b[option[0]]) ? -1 : 1;
}
}
}
return 0;
};
}
library.sort(priority(['album', 'disk', ['title', '-']])
library.sort(priority(['album', '-year', '+title']));
or
library.sort(priority('album', '-year', '+title'));
这将按相册升序、磁盘升序、标题降序对库进行排序
正式用法:
opt:包含以下内容的数组:
- 字符串(按升序对键“string”排序)
- 排列
- 0:字符串(对键“字符串”进行排序)
- 1:“-”或“+”表示升序或降序(默认为升序)
-
开头的键无法按升序排序
编辑:
替代版本,与'-album'
语法一起使用:
function priority(opt) {
if (!(opt instanceof Array)) {
opt = Array.prototype.slice.call(arguments);
}
return function (a, b) {
for (var i = 0; i < opt.length; ++i) {
var order = opt[i].substr(0, 1),
key = opt[i].substr(1);
if (order !== '-' && order !== '+') {
key = opt[i];
order = '+';
}
if (a[key] !== b[key]) {
if (a[key] === undefined) return 1;
if (b[key] === undefined) return -1;
if (typeof a[key] === 'string' || typeof b[key] === 'string') {
return (order === '+' ? String(a[key]).toLowerCase() < String(b[key]).toLowerCase() : String(a[key]).toLowerCase() > String(b[key]).toLowerCase()) ? -1 : 1;
} else {
return (order === '+' ? a[key] < b[key] : a[key] > b[key]) ? -1 : 1;
}
}
}
return 0;
};
}
您可以使用如下函数:
var library = [
{ "title": "40 Years Later", "album": "Tears of Steel", "year": 2012, "track": 1, "disk": 1, "time": 31 },
{ "title": "The Dome", "album": "Tears of Steel", "year": 2012, "track": 2, "disk": 1, "time": 311 },
{ "title": "The Battle", "album": "Tears of Steel", "year": 2012, "track": 3, "disk": 1, "time": 123 },
{ "title": "End Credits", "album": "Tears of Steel", "year": 2012, "track": 4, "disk": 1, "time": 103 },
{ "title": "The Wires", "album": "Elephants Dream", "year": 2006, "track": 1, "disk": 1, "time": 75 },
{ "title": "Typewriter Dance", "album": "Elephants Dream", "year": 2006, "track": 2, "disk": 1, "time": 70 },
{ "title": "The Safest Place", "album": "Elephants Dream", "year": 2006, "track": 3, "disk": 1, "time": 45 },
{ "title": "Emo Creates", "album": "Elephants Dream", "year": 2006, "track": 4, "disk": 1, "time": 60 },
{ "title": "End Title", "album": "Elephants Dream", "year": 2006, "track": 5, "disk": 1, "time": 91 },
{ "title": "Teaser Music", "album": "Elephants Dream", "year": 2006, "track": 6, "disk": 1, "time": 75 },
{ "title": "Ambience", "album": "Elephants Dream", "year": 2006, "track": 7, "disk": 1, "time": 110 },
{ "title": "Snow Fight", "album": "Sintel", "year": 2010, "track": 1, "disk": 1, "time": 107 },
{ "title": "Finding Scales / Chicken Run", "album": "Sintel", "year": 2010, "track": 2, "disk": 1, "time": 107 },
{ "title": "The Ziggurat", "album": "Sintel", "year": 2010, "track": 3, "disk": 1, "time": 78 },
{ "title": "Expedition", "album": "Sintel", "year": 2010, "track": 4, "disk": 1, "time": 93 },
{ "title": "Dragon Blood Tree", "album": "Sintel", "year": 2010, "track": 5, "disk": 1, "time": 47 },
{ "title": "Cave Fight / Lament", "album": "Sintel", "year": 2010, "track": 6, "disk": 1, "time": 145 },
{ "title": "I Move On (Sintel's Song)", "album": "Sintel", "year": 2010, "track": 7, "disk": 1, "time": 169 },
{ "title": "Circling Dragons", "album": "Sintel", "year": 2010, "track": 8, "disk": 1, "time": 28 },
{ "title": "Trailer Music", "album": "Sintel", "year": 2010, "track": 9, "disk": 1, "time": 44 }
];
function priority(opt) {
if (!(opt instanceof Array)) {
opt = Array.prototype.slice.call(arguments);
}
return function (a, b) {
for (var i = 0; i < opt.length; ++i) {
var option = opt[i];
if (typeof option === 'string') {
option = [option, '+'];
}
if (option.length < 2) {
option[1] = '+';
}
if (a[option[0]] !== b[option[0]]) {
if (a[option[0]] === undefined) return 1;
if (b[option[0]] === undefined) return -1;
if (typeof a[option[0]] === 'string' || typeof b[option[0]] === 'string') {
return (option[1] === '+' ? String(a[option[0]]).toLowerCase() < String(b[option[0]]).toLowerCase() : String(a[option[0]]).toLowerCase() > String(b[option[0]]).toLowerCase()) ? -1 : 1;
} else {
return (option[1] === '+' ? a[option[0]] < b[option[0]] : a[option[0]] > b[option[0]]) ? -1 : 1;
}
}
}
return 0;
};
}
library.sort(priority(['album', 'disk', ['title', '-']])
library.sort(priority(['album', '-year', '+title']));
or
library.sort(priority('album', '-year', '+title'));
这将按相册升序、磁盘升序、标题降序对库进行排序
正式用法:
opt:包含以下内容的数组:
- 字符串(按升序对键“string”排序)
- 排列
- 0:字符串(对键“字符串”进行排序)
- 1:“-”或“+”表示升序或降序(默认为升序)
-
开头的键无法按升序排序
编辑:
替代版本,与'-album'
语法一起使用:
function priority(opt) {
if (!(opt instanceof Array)) {
opt = Array.prototype.slice.call(arguments);
}
return function (a, b) {
for (var i = 0; i < opt.length; ++i) {
var order = opt[i].substr(0, 1),
key = opt[i].substr(1);
if (order !== '-' && order !== '+') {
key = opt[i];
order = '+';
}
if (a[key] !== b[key]) {
if (a[key] === undefined) return 1;
if (b[key] === undefined) return -1;
if (typeof a[key] === 'string' || typeof b[key] === 'string') {
return (order === '+' ? String(a[key]).toLowerCase() < String(b[key]).toLowerCase() : String(a[key]).toLowerCase() > String(b[key]).toLowerCase()) ? -1 : 1;
} else {
return (order === '+' ? a[key] < b[key] : a[key] > b[key]) ? -1 : 1;
}
}
}
return 0;
};
}
给你。。解决这个问题的一种方法是:
// This is kinda hacky, but it works
// "a" means do an alphabetical compare
// "n" means do a numeric compare.
var sortKeys = ["album", "a", "disk", "n", "track", "n", "title", "n"];
function byKey(ao, bo) {
var l = sortKeys.length;
var i = 0;
var sortResult;
// Walk through the keys
while (i < l) {
// Get the field name
var field = sortKeys[i];
// Get the compare type
var sortType = sortKeys[i + 1];
// Get the values and force to string values
var a = "" + ao[field];
var b = "" + bo[field];
console.log([field, sortType]);
// Advance by two because we consume two array elements
i += 2;
// Our alphabletical compare
if (sortType === "a") {
if (a.toLowerCase() < b.toLowerCase()) {
return -1;
}
if (a.toLowerCase() > b.toLowerCase()) {
return +1;
}
if (a.toLowerCase() === b.toLowerCase()) {
// Ok, these fields match. Restart the loop
// So it will try the next sort criteria in.
continue;
}
throw ("Should never actually get here.");
}
if (sortType === "n") {
// Cheap numeric compare
return +a - +b;
}
}
// A total match across all fields
return 0;
}
library.sort(byKey);
console.log(JSON.stringify(library, null, 2));
//这有点老套,但很管用
//“a”表示按字母顺序进行比较
//“n”表示进行数字比较。
var sortKeys=[“唱片”、“a”、“磁盘”、“n”、“曲目”、“n”、“标题”、“n”];
按键功能(ao、bo){
var l=sortKeys.length;
var i=0;
var sortResult;
//仔细检查钥匙
而(ib.toLowerCase()){
返回+1;
}
如果(a.toLowerCase()==b.toLowerCase()){
//好的,这些字段匹配。重新启动循环
//因此,它将在中尝试下一个排序条件。
持续
}
扔(“不应该真的到这里。”);
}
如果(sortType==“n”){
//廉价的数字比较
返回+a-+b;
}
}
//所有字段的总匹配
返回0;
}
library.sort(按键);
log(JSON.stringify(library,null,2));
给你。。解决这个问题的一种方法是:
// This is kinda hacky, but it works
// "a" means do an alphabetical compare
// "n" means do a numeric compare.
var sortKeys = ["album", "a", "disk", "n", "track", "n", "title", "n"];
function byKey(ao, bo) {
var l = sortKeys.length;
var i = 0;
var sortResult;
// Walk through the keys
while (i < l) {
// Get the field name
var field = sortKeys[i];
// Get the compare type
var sortType = sortKeys[i + 1];
// Get the values and force to string values
var a = "" + ao[field];
var b = "" + bo[field];
console.log([field, sortType]);
// Advance by two because we consume two array elements
i += 2;
// Our alphabletical compare
if (sortType === "a") {
if (a.toLowerCase() < b.toLowerCase()) {
return -1;
}
if (a.toLowerCase() > b.toLowerCase()) {
return +1;
}
if (a.toLowerCase() === b.toLowerCase()) {
// Ok, these fields match. Restart the loop
// So it will try the next sort criteria in.
continue;
}
throw ("Should never actually get here.");
}
if (sortType === "n") {
// Cheap numeric compare
return +a - +b;
}
}
// A total match across all fields
return 0;
}
library.sort(byKey);
console.log(JSON.stringify(library, null, 2));
//这有点老套,但很管用
//“a”表示按字母顺序进行比较
//“n”表示进行数字比较。
var sortKeys=[“唱片”、“a”、“磁盘”、“n”、“曲目”、“n”、“标题”、“n”];
按键功能(ao、bo){
var l=sortKeys.length;
var i=0;
var sortResult;
//仔细检查钥匙
而(ib.toLowerCase()){
返回+1;
}
如果(a.toLowerCase()==b.toLowerCase()){
//好的,这些字段匹配。重新启动循环
//因此,它将在中尝试下一个排序条件。
持续
}
扔(“不应该真的到这里。”);
}
如果(sortType==“n”){
//廉价的数字比较
返回+a-+