[英]How to sort set of numbers both lexicographically and numerically?
我目前有一組字符串,只是數字和數字+或 - 。 如下:
1,1 +,1,2,2 +,2-,10
當我使用JavaScript的排序函數排序時,它給出:
1,1 +,1,10,2,2 +,2-
這是按字典順序但不是數字的。 有沒有辦法對它進行排序,以便數字以正確的方式出現(第一個列表)? 我正在使用ExtJS商店,所以作為商店分揀機的答案是首選,但普通的javascript也沒關系。 謝謝 ?
編輯:這不只是排序數字。
您可以使用自定義排序功能,如下所示:
var numbers = ['1', '1-', '1+', '2', '2+', '2-', '10']; numbers.sort(function (a, b){ var _a = parseFloat(a), // If the values are integers only, parseInt will do too _b = parseFloat(b); if (_a - _b === 0) { return (a > b) ? 1 : -1; } else { return _a - _b; } }); console.log(numbers);
該函數檢查數值是否相等,如果是,則返回到詞典排序以對字符后綴進行排序。 如果在相同的情況下沒有后綴,則無論返回數字的順序如何。 如果只有一個操作數具有后綴,則裸號返回負數。 如果數值不相等,則函數只返回三態,即a - b
,它將被評估為negative, 0, positive
。 或者實際上它是“bistate”,因為我們已經處理了0
案例。
更通用的解決方案
上面的代碼只是兩個不同的單個字符后綴的特殊情況。 如果后綴更復雜,這里有一個更通用的代碼,按數字和后綴排序:
var numbers = ['1', '1-r', '1+q', '1', '2', '2+q', '2-r', '10']; function suffixSort (suff, asc) { asc = 2 * +(!!asc) - 1; // Convert boolean to -1 or 1 return function (a, b) { var _a = parseFloat(a), // Extract the number value _b = parseFloat(b), aSI = -(a.length - _a.toString().length), // Get the index of suffix start bSI = -(b.length - _b.toString().length); // Equal number values, sort by suffixes if (_a === _b) { return (suff.indexOf(a.substr(aSI)) > suff.indexOf(b.substr(bSI))) ? 1 : -1; } // Inequal number values, sort by numbers return asc * (_a - _b); } } // suffixSort arguments // suff: An array of the suffix strings to sort, ordered in the desired sorting order // asc: true = ascending, false = descending. Optional, defaults to descending sort numbers.sort(suffixSort(['+q', '-r'], true)); console.log(numbers);
想法是將后綴存儲到數組中,並且當需要后綴排序時,函數比較后綴的數組索引而不是后綴本身。
suffixSort
還允許您決定排序方向。 選定的排序方向對后綴排序沒有影響,它們總是按它們在suff
數組中出現的順序返回。
您可以使用Array#sort
並將數字和其余元素拆分,然后返回差異或順序的差異。
var array = ['10', '2', '2+', '2-', '1', '1+', '1-']; array.sort(function (a, b) { var r = /\\d+|\\D+/g, aa = a.match(r), bb = b.match(r), order = { '+': 1, '-': 2 }; return aa[0] - bb[0] || (order[aa[1]] || 0) - (order[bb[1]] || 0); }); console.log(array);
var result=[];
result=array.map(function(n){
if(typeof n==='number') return n;
if(n[n.length-1]=='+'){
return parseInt(n.substring(0,n.length-1))
}
else if(n[n.length-1]=='-'){
return 0-parseInt(n.substring(0,n.length-1))
}
});
result.sort(function(a,b){return a-b})
這些值幾乎是整數,因此根據praseInt
比較它們幾乎可以讓你到達那里。 唯一缺少的是對具有相同整數部分的值的特殊處理,其中x-
應該首先出現,然后是x
,最后是x+
:
function specialChar(s) {
c = s.substr(-1);
if (c == '+') {
return 1;
}
if (c == '-') {
return -1;
}
return 0;
}
function numCompare(a, b) {
aNum = parseInt(a);
bNum = parseInt(b);
cmp = aNum - bNum;
if (cmp != 0) {
return cmp;
}
// Integer parts are equal - compare the special char at the end
return specialChar(a) - specialChar(b);
}
arr = ['1' , '1+', '1-', '2', '2+', '2-', '10'];
arr.sort(numCompare);
如果只有三個可能的數字狀態,並且狀態具有訂單number, number+, number
,則可以通過創建數字的數組表示來重新創建狀態,從數組中刪除唯一數字,從最小到最大,連接空字符串或算術運算符按所需順序排列,然后將值推送到數組,其中.toString()
可用於查看數組中排序值的逗號分隔字符串表示形式
var str = `314+, 1-, 7+, 1, 1-, 271-, 10- , 10+, 271, 271+, 314-, 314 , 10, 2-, 2, 2+, 7-, 7`; for (var [nums, order, res, num] = [str.match(/\\d+/g), ["", "+", "-"], [], null] ; nums.length ; num = Math.min.apply(Math, nums) , res = [...res, ...order.map(op => num + op)] , nums = nums.filter(n => n != num) ); console.log(res.toString() + "\\n", res);
假設您只想丟棄符號,那么您可以使用parseInt和Array#sort以數字方式獲取順序。
var data = ['1' , '1+', '1-', '2', '2+', '2-', '10'];
var sortedData = data.sort(function(a,b){return parseInt(a)-parseInt(b);});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.