如何正确对包含正负数字与字符串的混合数组排序?
Let's fix that mixed array sorting issue you're facing. The problem with your original localeCompare approach is that it doesn't prioritize numeric values over alphabetic ones—so even with numeric sorting enabled, strings like -2 end up getting mixed in with letters instead of grouping together first.
Here are two clean, efficient ways to get your desired output:
Option 1: Split, Sort Separately, Merge (Efficient)
This approach splits the array into numeric and alphabetic groups, sorts each group appropriately, then combines them. It's often faster than sorting a single mixed array, especially with larger datasets:
const originalArr = ['a', 'A', 'B', '-1.50', '0', '1.50', '-2', '2']; // Split into numeric and alphabetic subgroups const [numericItems, alphaItems] = originalArr.reduce((groups, item) => { // Check if the item is a valid numeric string !isNaN(Number(item)) ? groups[0].push(item) : groups[1].push(item); return groups; }, [[], []]); // Sort numeric items by their actual numeric value numericItems.sort((a, b) => Number(a) - Number(b)); // Sort alphabetic items case-insensitively alphaItems.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' })); // Combine the sorted groups (numbers first, then letters) const sortedArr = [...numericItems, ...alphaItems]; console.log(sortedArr); // ["-2", "-1.50", "0", "1.50", "2", "A", "a", "B"]
Option 2: Single Sort Function (Concise)
If you prefer a one-step approach, you can handle the grouping logic directly inside the sort comparator. This keeps the code compact while achieving the same result:
const originalArr = ['a', 'A', 'B', '-1.50', '0', '1.50', '-2', '2']; const sortedArr = originalArr.sort((a, b) => { const aIsNumeric = !isNaN(Number(a)); const bIsNumeric = !isNaN(Number(b)); // Both are numbers: sort numerically if (aIsNumeric && bIsNumeric) return Number(a) - Number(b); // Only a is number: it comes first if (aIsNumeric) return -1; // Only b is number: it comes first if (bIsNumeric) return 1; // Both are letters: sort case-insensitively return a.localeCompare(b, undefined, { sensitivity: 'base' }); }); console.log(sortedArr); // ["-2", "-1.50", "0", "1.50", "2", "A", "a", "B"]
Key Notes:
- The
isNaN(Number(item))check works for valid numeric strings (including negatives and decimals like-1.50). - Using
sensitivity: 'base'inlocaleCompareensures case-insensitive sorting (soAandaare treated as equivalent and ordered naturally).
内容的提问来源于stack exchange,提问作者Ali Ankarali

