我继承了一个系统,该系统利用需要根据一系列值进行排序的文件的 Backbone 集合。当您将不同的文件滑入视图中的某个位置时,将保存顺序变量。它大多数情况下都可以工作,但偶尔会出现无法根据 files_order 列表中的值正确排序的情况。我发现使用无符号右移最接近工作,但代码返回奇怪的结果,因为集合中的许多文件不在 files_order 中。
对于filecollectionid = 1,系统结果为: 36528,36524,36529,35526,36523,36525,36530,36531
正确的顺序应该是: 36528,36523,36524,36525,35526,36529,36530,36531
我假设列表中不存在的变量的无符号右移导致了问题。任何帮助将不胜感激。
collection = new Backbone.Collection([
{ id: 36523, name: "File 1", filecollectionid: 1 },
{ id: 36524, name: "File 2", filecollectionid: 1 },
{ id: 36525, name: "File 3", filecollectionid: 1 },
{ id: 36526, name: "File 4", filecollectionid: 1 },
{ id: 36528, name: "File 5", filecollectionid: 1 },
{ id: 36529, name: "File 6", filecollectionid: 1 },
{ id: 36530, name: "File 7", filecollectionid: 1 },
{ id: 36531, name: "File 8", filecollectionid: 1 },
{ id: 36476, name: "Video 1", filecollectionid: 6 },
{ id: 36520, name: "Video 2", filecollectionid: 6 },
{ id: 36527, name: "Video 3", filecollectionid: 6 }
]);
sections = {
"id": 1,
"files_order" : [36503,36513,36505,36506,36507,36508,36509,36510,36511,36521,36528,36522,35523,36524]
}
collection.sort(function(a,b) {
// Lets group files by the file collection id first
if(a.filecollectionid != b.filecollectionid){
return a.filecollectionid - b.filecollectionid;
}
// Lets try to use the files_order variable
try {
// Get the files_order field
var files_order = _.find(sections, function(section) {
// They should both have the same filecollectionid
return a.filecollectionid == section.id;
}).files_order;
files_order = _.map(JSON.parse(files_order.toString()), function(item) {
return parseInt(item);
});
// use unsigned right shift to keep the original and add the unadded to the end
return (files_order.indexOf(a.id) >>> 0) - (files_order.indexOf(b.id) >>> 0);
} catch(e) {
// If no sorting order this really should be oldest first and newest last.
a = a.id;
b = b.id;
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
}
});
假设你可以使用当前版本的JS:
(() => {
const collection = [
{ id: 36524, name: "File 2", filecollectionid: 1 },
{ id: 36523, name: "File 1", filecollectionid: 1 },
{ id: 36525, name: "File 3", filecollectionid: 1 },
{ id: 36520, name: "Video 2", filecollectionid: 6 },
{ id: 36526, name: "File 4", filecollectionid: 1 },
{ id: 36528, name: "File 5", filecollectionid: 1 },
{ id: 36529, name: "File 6", filecollectionid: 1 },
{ id: 36476, name: "Video 1", filecollectionid: 6 },
{ id: 36530, name: "File 7", filecollectionid: 1 },
{ id: 36531, name: "File 8", filecollectionid: 1 },
{ id: 36527, name: "Video 3", filecollectionid: 6 },
];
const sections = [
{
id: 1,
files_order: [36503, 36513, 36505, 36506, 36507, 36508, 36509, 36510, 36511, 36521, 36528, 36522, 35523, 36524],
},
];
const getOrderMap = (collectionId) => {
const order = sections.find((s) => s.id === collectionId)?.files_order ?? [];
return new Map(order.map((v, i) => [v, i]));
};
collection.sort(function (a, b) {
if (a.filecollectionid != b.filecollectionid) {
return a.filecollectionid - b.filecollectionid;
}
const map = getOrderMap(a.filecollectionid);
const [ai, bi] = [map.get(a.id), map.get(b.id)];
return ai === bi ? a.id - b.id : ai === undefined ? 1 : bi === undefined ? -1 : ai - bi;
});
// Debugging purposes
console.log(collection);
})();