javascript - 如何按值按降序对文件大小字符串列表进行排序
问题描述
我正在尝试智能地对文件大小字符串的列表/数组进行排序(升序或降序)。字符串格式数字(带或不带小数)后跟空格,然后是单位。
例如 - ["5.1 GB", "19934563 B","224 kB","0.55 GB","0.04 kB","0.02 TB","2.4 MB",] 结果为 ["0.02 TB", " 5.1 GB”、“0.55 GB”、“19934563 B”、“2.4 MB”、“224 kB”、“0.04 kB”]
这是我到目前为止所拥有的:
if (!fileSizes.length) return "Enter an List to be Sorted";
else {
//Check input formart of strings
let validFormat = fileSizes.map((file) => validFile(file));
if (validFormat.includes(false)) return "Invalid Input format";
else {
let myfiles = reOrderFormat(fileSizes);
if (descending === true) {
sorter = MySort("TGMkB");
let mysortedFiles = myfiles.sort(sorter);
//sort by number for repeated file sizes
let result = reOrderFormat(mysortedFiles);
return result;
} else {
sorter = MySort("BkMGT");
let mysortedFiles = myfiles.sort(sorter);
//sort by number for repeated file sizes
let result = reOrderFormat(mysortedFiles);
return result;
}
}
}
}
//Helper Functions for checking input format
//Regular expression for correct input format
function validFile(str) {
let regEx = /^(-?\d*(\.\d+)?)\s((T|G|M|k)*B)$/;
let valid = regEx.test(str);
return valid;
}
//Checks if input is in right format
function validList(arr) {
let validArray = arr.map((fileSiz) => validFile(fileSiz));
return arr;
}
//Helper functions for sorting and reoredering input format
//Format reordering function
function reOrderFormat(arr) {
let reOrdered = [];
arr.map((file) => {
let out = file.split(" ");
let first = out[1];
let second = out[0];
let newOrder = first + " " + second;
reOrdered.push(newOrder);
});
return reOrdered;
}
//Custom sorter
function MySort(alphabet) {
return function (a, b) {
var index_a = alphabet.indexOf(a[0]),
index_b = alphabet.indexOf(b[0]);
if (index_a === index_b) {
// same first character, sort regular
if (a < b) {
return -1;
} else if (a > b) {
return 1;
}
return 0;
} else {
return index_a - index_b;
}
};
}
sort(
["5.1 GB", "19934563 B", "224 kB", "0.55 GB", "0.04 kB", "0.02 TB", "2.4 MB"],
true
);
它不会相应地对重复的单元进行排序,并且还会混淆以字节为单位的长数字。
我需要帮助编码更有效的东西。
解决方案
我能够在按比较器排序的帮助下解决您的问题,我构建了全局数组:let sizes = ["B", "kB", "MB", "GB", "TB"];
按大小顺序。考虑您的 main 函数被称为 main 如下,sortSizes
在 arr 上使用该函数后,返回数组应该是预期的数组:
function main() {
let arr = ["5.1 GB", "19934563 B","224 kB","0.55 GB","0.04 kB","0.02 TB","2.4 MB",];
let expected = ["0.02 TB", "5.1 GB", "0.55 GB", "19934563 B", "2.4 MB", "224 kB", "0.04 kB"];
let new_arr = sortSizes(arr);
console.log(new_arr);
console.log(expected);
}
两个 console.log 都应该打印相同的排序数组。
// global array
let sizes = ["B", "kB", "MB", "GB", "TB"];
function sortSizes(arr) {
// sort by comperator
arr.sort(function(x, y) {
var x_res = x.split(" "), y_res = y.split(" ");
var x_value = x_res[0], x_unit = x_res[1];
var y_value = y_res[0], y_unit = y_res[1];
let amount = casting(x_unit, y_unit, x_value);
if(amount < y_value) {
return -1;
} else if(x_value > y_value) {
return 1;
} else {
return 0;
}
});
return arr.reverse();
}
转换函数是获取两个单位和数量,并将第一个数量转换为第二个数量后返回数量,例如:从 5.1 GB 到 B 应该是:5476083302.4 B。
function casting(unit_from, unit_to, amount) {
var i = sizes.indexOf(unit_from);
var j = sizes.indexOf(unit_to);
var r;
if(i < j) {
r = j - i;
} else {
r = j - i;
}
var i = 0;
if(r < 0) {
r *= (-1);
while(i < r) {
amount *= 1024;
i++;
}
} else {
while(i < r) {
amount /= 1024;
i++;
}
}
return amount;
}
推荐阅读
- javascript - 在地图内拟合边界
- c++ - 为什么 C++ 整数检查器不能正常工作?
- c# - 在大型 Unity/C# 游戏中过滤通用集合的理想性能
- flutter - 当我在 Android Studio 中增加 sd 卡内存时,模拟器从 AVD 管理器中删除
- html - 未显示用户名文本输入
- oauth - JavaMail oauth 需要完整的邮件范围才能通过 gmail 发送电子邮件
- mysql - Mysql/Doctrine - 检查月份是否在两个日期之间
- python - 在张量流中找到所有特征的最大值
- template-engine - 在 Jinjava 中渲染一个循环?
- java - 如何从链接列表中删除值?