使用 lodash/Javascript 对数字数组进行排序
Sort number array using lodash/Javascript
我有一个字符串数组如下。
let arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
我想要如下所示的预期输出。
["1+", "1", "1-", "2+", "2", "2-", "3+", "3", "3-", "4", "10"];
我尝试了下面的代码,但没有给出正确的结果。
let arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
let result = arr.sort((a,b) => {
return a.localeCompare(b, undefined, {
numeric: true,
sensitivity: 'base',
});
});
console.log(result);
因此,您需要用于数字和符号的比较器。
一般概念:
您可以这样定义符号优先级:
const signPriority = {
'+': 0,
'n': 1, // n = no sign
'-': 2,
}
其中 key
是符号,value
是我们将在比较器中使用的符号权重('n'
表示“无符号”)。
然后我们将数组元素拆分为数字和符号,在比较器函数中并分别进行比较:
arr.sort((a, b) => {
// If numbers are different ...
if (parseInt(a) !== parseInt(b)) {
// Just compare a numbers
return parseInt(a) - parseInt(b);
} else {
// If sign matter ...
// Extract sign from element or define as 'n' if no sign found
const sign_a = ['+', '-'].includes(a.slice(-1)) ? a.slice(-1) : 'n';
const sign_b = ['+', '-'].includes(b.slice(-1)) ? b.slice(-1) : 'n';
// Compare signs using their weight
return signPriority[sign_a] - signPriority[sign_b];
}
})
完整解:
const signPriority = {
'+': 0,
'n': 1,
'-': 2,
}
const arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
const sorted = arr.sort((a, b) => {
if (parseInt(a) !== parseInt(b)) {
return parseInt(a) - parseInt(b);
} else {
const sign_a = ['+', '-'].includes(a.slice(-1)) ? a.slice(-1) : 'n';
const sign_b = ['+', '-'].includes(b.slice(-1)) ? b.slice(-1) : 'n';
return signPriority[sign_a] - signPriority[sign_b];
}
})
console.log(sorted);
您应该尝试将字符串转换为十进制数,然后进行比较。
例如,如果将“2+”转换为 1.9,将“2-”转换为 2.1,则可以将值作为数字进行比较。
const arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
function convertToNumber(text) {
const offset = text.endsWith("+") ? -0.1 : text.endsWith("-") ? 0.1 : 0;
if (text.endsWith("+") || text.endsWith("-")) {
text = text.substring(0, text.length - 1);
}
return parseFloat(text) + offset;
}
const sorted = arr.sort((a, b) => {
return convertToNumber(a) > convertToNumber(b);
});
console.log("Sorted: ", sorted);
使用正则表达式单词边界拆分每个字符串。使用解构得到字符串形式的数字(an
、bn
)和符号(as
、bs
)。如果符号是 undefined
使用逗号作为回退,因为逗号在 ascii table.
中位于 +
和 -
之间
return 值应该是 an - bn
(auto-casted 数字的差),如果是 0
则使用 bs?.localeCompare(as)
排序签名。
const arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
const getNumAndSign = str => str.split(/\b/)
const sorted = arr.sort((a, b) => {
const [an, as = ','] = getNumAndSign(a)
const [bn, bs = ','] = getNumAndSign(b)
return +an - +bn || bs?.localeCompare(as)
})
console.log(sorted);
我有一个字符串数组如下。
let arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
我想要如下所示的预期输出。
["1+", "1", "1-", "2+", "2", "2-", "3+", "3", "3-", "4", "10"];
我尝试了下面的代码,但没有给出正确的结果。
let arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
let result = arr.sort((a,b) => {
return a.localeCompare(b, undefined, {
numeric: true,
sensitivity: 'base',
});
});
console.log(result);
因此,您需要用于数字和符号的比较器。
一般概念:
您可以这样定义符号优先级:
const signPriority = {
'+': 0,
'n': 1, // n = no sign
'-': 2,
}
其中 key
是符号,value
是我们将在比较器中使用的符号权重('n'
表示“无符号”)。
然后我们将数组元素拆分为数字和符号,在比较器函数中并分别进行比较:
arr.sort((a, b) => {
// If numbers are different ...
if (parseInt(a) !== parseInt(b)) {
// Just compare a numbers
return parseInt(a) - parseInt(b);
} else {
// If sign matter ...
// Extract sign from element or define as 'n' if no sign found
const sign_a = ['+', '-'].includes(a.slice(-1)) ? a.slice(-1) : 'n';
const sign_b = ['+', '-'].includes(b.slice(-1)) ? b.slice(-1) : 'n';
// Compare signs using their weight
return signPriority[sign_a] - signPriority[sign_b];
}
})
完整解:
const signPriority = {
'+': 0,
'n': 1,
'-': 2,
}
const arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
const sorted = arr.sort((a, b) => {
if (parseInt(a) !== parseInt(b)) {
return parseInt(a) - parseInt(b);
} else {
const sign_a = ['+', '-'].includes(a.slice(-1)) ? a.slice(-1) : 'n';
const sign_b = ['+', '-'].includes(b.slice(-1)) ? b.slice(-1) : 'n';
return signPriority[sign_a] - signPriority[sign_b];
}
})
console.log(sorted);
您应该尝试将字符串转换为十进制数,然后进行比较。 例如,如果将“2+”转换为 1.9,将“2-”转换为 2.1,则可以将值作为数字进行比较。
const arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
function convertToNumber(text) {
const offset = text.endsWith("+") ? -0.1 : text.endsWith("-") ? 0.1 : 0;
if (text.endsWith("+") || text.endsWith("-")) {
text = text.substring(0, text.length - 1);
}
return parseFloat(text) + offset;
}
const sorted = arr.sort((a, b) => {
return convertToNumber(a) > convertToNumber(b);
});
console.log("Sorted: ", sorted);
使用正则表达式单词边界拆分每个字符串。使用解构得到字符串形式的数字(an
、bn
)和符号(as
、bs
)。如果符号是 undefined
使用逗号作为回退,因为逗号在 ascii table.
+
和 -
之间
return 值应该是 an - bn
(auto-casted 数字的差),如果是 0
则使用 bs?.localeCompare(as)
排序签名。
const arr = ["1", "1+", "1-","2", "2+", "3","3+", "2-", "3-", "4", "10"];
const getNumAndSign = str => str.split(/\b/)
const sorted = arr.sort((a, b) => {
const [an, as = ','] = getNumAndSign(a)
const [bn, bs = ','] = getNumAndSign(b)
return +an - +bn || bs?.localeCompare(as)
})
console.log(sorted);