字符串无序拼接实现优化及自定义排序需求技术问询
Great question! Your current sorting-and-joining approach works for the core requirement, but we can refine it for better performance (especially with duplicate strings) and add support for custom ordering rules. Let's dive in:
1. Pros & Cons of the Current Sorting Approach
Your existing code:
function newConcat( ...strings ) { const newArray = [] newArray.push(...strings) return newArray.sort().join("") }
does exactly what you need: it ensures the same output regardless of input order by sorting strings by their Unicode code points. But it has two areas for improvement:
- Performance with duplicates: If you have lots of repeated strings (e.g., 1000 instances of "Pen"), sorting all of them wastes cycles comparing identical values.
- Rigid ordering: The default Unicode sort might not align with your desired logic (e.g., you might want shorter strings first, or specific strings to always come first).
2. A More Efficient Implementation (For Duplicate-Heavy Inputs)
When dealing with many repeated strings, we can first count occurrences, sort only the unique strings, then repeat them according to their counts. This cuts down on the number of elements we need to sort:
function newConcat(...strings) { // Track how many times each string appears const stringCounts = new Map(); for (const str of strings) { stringCounts.set(str, (stringCounts.get(str) || 0) + 1); } // Sort unique strings, then repeat each by its count and join return Array.from(stringCounts.keys()) .sort() .map(str => str.repeat(stringCounts.get(str))) .join(""); }
For inputs with few duplicates, this is roughly as fast as your original code. But for duplicate-heavy inputs, it’s significantly more efficient. If you don’t expect many duplicates, you can even simplify your original code to a one-liner:
const newConcat = (...strings) => [...strings].sort().join("");
3. Adding Custom Concatenation Order
If you want to define your own ordering rules (instead of relying on Unicode), you have two straightforward options:
Option 1: Custom Sort Comparator
Define a function that tells sort() how to compare two strings. For example, to sort by string length (longest first), then alphabetically:
function newConcat(...strings) { return [...strings].sort((a, b) => { // First sort by length (descending) if (a.length !== b.length) { return b.length - a.length; } // If lengths are equal, fall back to alphabetical order return a.localeCompare(b); }).join(""); }
Option 2: Priority Mapping
Create a predefined priority list for specific strings, so they always appear in your desired order. Any strings not in the map fall back to default sorting:
function newConcat(...strings) { // Define custom priority: lower numbers = earlier in the result const priority = { "Apple": 1, "Pen": 2, "Pineapple": 3 }; return [...strings].sort((a, b) => { // Both strings have defined priorities: sort by priority if (priority[a] && priority[b]) { return priority[a] - priority[b]; } // One or both don't have priorities: fall back to Unicode order return a.localeCompare(b); }).join(""); }
4. Handling Empty Strings (As Per Your Requirements)
Your requirement that newConcat("Pen", "Apple") === newConcat("", "PenApple") (or equivalent for "ApplePen") is automatically satisfied by all these implementations. Empty strings have the lowest Unicode code point, so they’ll sort to the front—but concatenating an empty string with another string leaves the result unchanged. For example:
["Pen", "Apple"].sort().join("")→ "ApplePen"["", "ApplePen"].sort().join("")→ "" + "ApplePen" = "ApplePen"
Which matches exactly. If you’re using a custom sort, just ensure empty strings either sort to the front (so they don’t affect the non-empty result) or adjust your comparator to handle them explicitly if needed.
内容的提问来源于stack exchange,提问作者Terry

