我在使用优先级队列方法排序字符串时遇到问题。这是我排序的字符串键的一个例子:
[ '.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5' ]
值是需要从最小到最大排序的层次结构的表示。我期待的结果是:
[ '.0', '.1', '.2.1', '.2, '.3', '.4', '.4.1', '.5', '.5.1.5' ]
我用于推入队列的方法在O(log n)
运行,如下所示:
queue.add = function(myval) {
// console.log(myval);
var i = this.size;
this.array[this.size++] = myval;
while ( i > 0) {
var p = (i - 1) >> 1;
var ap = this.array[p];
if(!this.compare(myval, ap )) break;
this.array[i] = ap;
i = p;
}
};
我的比较功能很简单:
(a, b) => {
return a[0] < b[0];
}
我正在考虑使用localeCompare但是因为我在Node中它似乎并不是出于某些原因而可靠。当我使用时:
(a, b) => {
return a[0].localeCompare(b[0]) > 0;
}
我得到一个compareLocal未定义的错误,可能与其他内容有关。
因此,我的问题是,如何以我概述的方式有效地确定字符串排序?
答案 0 :(得分:0)
虽然我的结果如下:
[".0", ".1", ".2", ".2.1", ".3", ".4", ".4.1", ".5", ".5.1.5"]
我希望这有帮助,我使用insert-sort来对这些值进行排序:
var arr = [ '.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5' ];
// transform these values into '.21' or '.515' so that they can be sorted better
var transormedArray = arr.map(function(ele){
return '.'+ele.replace(/[.]/g,'');
});
// insertion sort max-iterations n^2, min-iterations n(if already ordered)
for(var i=1; i< transormedArray.length; i++){
for(var r=i; r>=0 && transormedArray[r-1]>transormedArray[r]; r--){
var tmp = transormedArray[r];
transormedArray[r] = transormedArray[r-1];
transormedArray[r-1] = tmp;
}
}
// retransform them back into '.2.1' or '.5.1.5'
var result = transormedArray.map(function(ele){
var str = ele.toString()[0];
for(var i=1; i< ele.toString().length; i++){
str += ele.toString()[i]+'.';
}
return str.slice(0,str.length-1);
});
console.log(result); // [".0", ".1", ".2", ".2.1", ".3", ".4", ".4.1", ".5", ".5.1.5"]
答案 1 :(得分:0)
您可以拆分字符串并比较各部分。
function customSort(data, order) {
function isNumber(v) {
return (+v).toString() === v;
}
var sort = {
asc: function (a, b) {
var i = 0,
l = Math.min(a.value.length, b.value.length);
while (i < l && a.value[i] === b.value[i]) {
i++;
}
if (i === l) {
return a.value.length - b.value.length;
}
if (isNumber(a.value[i]) && isNumber(b.value[i])) {
return a.value[i] - b.value[i];
}
return a.value[i].localeCompare(b.value[i]);
},
desc: function (a, b) {
return sort.asc(b, a);
}
},
mapped = data.map(function (el, i) {
return { index: i, value: el.split('.') };
});
mapped.sort(sort[order] || sort.asc);
return mapped.map(function (el) {
return data[el.index];
});
}
var array = ['.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5'];
console.log('sorted array asc', customSort(array));
console.log('sorted array desc ', customSort(array, 'desc'));
console.log('original array ', array);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 2 :(得分:0)
您可以创建一个自定义排序比较器方法,该方法将值拆分并比较它们的长度;及其整数值。
这是最简单,最直接的方法。
var compareVersions = (a, b) => {
if (a === b) return 0;
var aArr = a.split("."), bArr = b.split(".");
for (var i = 0; i < Math.min(aArr.length, bArr.length); i++) {
if (parseInt(aArr[i]) < parseInt(bArr[i])) return -1;
if (parseInt(aArr[i]) > parseInt(bArr[i])) return 1;
}
if (aArr.length < bArr.length) return -1;
if (aArr.length > bArr.length) return 1;
return 0;
};
var compareVersionsDesc = (a, b) => compareVersions(b, a);
// Example
let versionArr = ['.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5'];
console.log('Original Array: ', JSON.stringify(versionArr));
console.log('Sort Ascending:', JSON.stringify(versionArr.sort(compareVersions)));
console.log('Sort Descending:', JSON.stringify(versionArr.sort(compareVersionsDesc)));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;