Мне нужно изощренно отсортировать несколько больших массивов (1000-2000 ключей) для моего веб-приложения.Я немного поработал в Safari 12.0 / FF 66.0, но chrome 74.0, похоже, делает что-то совсем другое.
Последовательность, которую я хочу отсортировать - без учета регистра, с естественным регистром:
1. "scene"
2. "shot"
3. "take"
4. "name"
Каждое из этих значений может быть строкой (например, 4
, 4b
или 4-PU üöä!"
) или 'undefined' и может выглядеть следующим образом:
[
{"scene": "1", "shot": "1", "take": "4", "name": "A031C006_170718_R1W0"},
{"scene": "8", "shot": "8", "take": "4", "name": "A020C004_170716_R1W0"},
{"scene": "1", "shot": "1", "take": "10", "name": "A031C013_170718_R1W0"},
{"scene": undefined, "shot": undefined, "take": undefined, "name": "A001C549_190226_R04Q"},
{"scene": "2", "shot": "2", "take": "1", "name": "A008C010_170715_R1W0"},
{"scene": "5", "shot": "5", "take": "1", "name": "A015C005_170716_R1W0"},
{"scene": "3", "shot": "3", "take": "7", "name": "A002C003_170714_R1W0"},
{"scene": "5", "shot": "5", "take": "5", "name": "A021C005_170716_R1W0"},
{"scene": "5", "shot": "5", "take": "9", "name": "A024C006_170717_R1W0"},
{"scene": "1", "shot": "1", "take": "3", "name": "A004C006_170714_R1W0"},
{"scene": "1-b", "shot": "1", "take": "3", "name": "A004C007_170718_R1W0*"},
{"scene": "5", "shot": "5PU", "take": "6", "name": "A021C005_170716_R1W0*"},
]
Если клавиша scene
имеетне существует, сортируйте до конца и сортируйте по «имени».
Это часть проекта vue.js, и я надеюсь сделать это без дополнительной библиотеки.
Вот моя функциядо сих пор.Я использую localCompare()
для сравнения, например.4a
до 4
или 4ä
.Я уверен, что это очень медленно и может быть намного лучше!
sortedFiles = sortClips(files)
sortClips(clips) {
let firstBy=(function(){function e(f){f.thenBy=t;return f}function t(y,x){x=this;return e(function(a,b){return x(a,b)||y(a,b)})}return e})();
let options = {
numeric: true,
sensitivity: 'base',
ignorePunctuation: true
};
clips.sort(
firstBy(function (v1, v2) {
if (!v1.scene) {
return v1.name.localeCompare(v2.name, undefined, options);
}
return v1.scene.localeCompare(v2.scene, undefined, options);
})
.thenBy(function (v1, v2) {
if (!v1.shot) return -1;
return v1.shot.localeCompare(v2.shot, undefined, options);
})
.thenBy(function (v1, v2) {
if (!v1.take) return -1;
return v1.take.localeCompare(v2.take, undefined, options);
})
);
return clips;
},
Исходные данные (сцена, снимок, дубль, имя):
1 1 4 A031C006_170718_R1W0
8 8 4 A020C004_170716_R1W0
1 1 10 A031C013_170718_R1W0
undefined undefined undefined "A001C549_190226_R04Q"
2 2 1 A008C010_170715_R1W0
5 5 1 A015C005_170716_R1W0
3 3 7 A002C003_170714_R1W0
5 5 5 A021C005_170716_R1W0
5 5 9 A024C006_170717_R1W0
1 1 3 A004C006_170714_R1W0
1-b 1 3 A004C007_170718_R1W0*
5 5PU 6 A021C005_170716_R1W0*
Firefox / safari sorts:
8 8 4 A020C004_170716_R1W0
1 1 4 A031C006_170718_R1W0
1 1 10 A031C013_170718_R1W0
undefined undefined undefined A001C549_190226_R04Q
5 5 1 A015C005_170716_R1W0
5 5 9 A024C006_170717_R1W0
3 3 7 A002C003_170714_R1W0
5 5 5 A021C005_170716_R1W0
1 1 3 A004C006_170714_R1W0
2 2 1 A008C010_170715_R1W0
1-b 1 3 A004C007_170718_R1W0*
5 5PU 6 A021C005_170716_R1W0*
Chrome сортирует по-разному:
5 5 1 A015C005_170716_R1W0
5 5 9 A024C006_170717_R1W0
3 3 7 A002C003_170714_R1W0
5 5 5 A021C005_170716_R1W0
1 1 3 A004C006_170714_R1W0
undefined undefined undefined "A001C549_190226_R04Q"
8 8 4 A020C004_170716_R1W0
1 1 4 A031C006_170718_R1W0
1 1 10 A031C013_170718_R1W0
2 2 1 A008C010_170715_R1W0
1-b 1 3 A004C007_170718_R1W0*
5 5PU 6 A021C005_170716_R1W0*
Цель:
1 1 3 A004C006_170714_R1W0
1 1 4 A031C006_170718_R1W0
1 1 10 A031C013_170718_R1W0
1-b 1 3 A004C007_170718_R1W0*
2 2 1 A008C010_170715_R1W0
3 3 7 A002C003_170714_R1W0
5 5 1 A015C005_170716_R1W0
5 5 5 A021C005_170716_R1W0
5 5PU 6 A021C005_170716_R1W0*
5 5 9 A024C006_170717_R1W0
8 8 4 A020C004_170716_R1W0
undefined undefined undefined A001C549_190226_R04Q
Как мне отсортировать то, что я хочу?
ОБНОВЛЕНИЕ:
Я включил крайние случаи:
Сцена "1-b" добавленные символы "-b" должны быть отсортированы после всех элементов ссцена «1», когда ключ «сцена».
выстрел «5PU» добавленные символы «PU» следует игнорировать, когда ключ «выстрел» или «взять».