如何将含重复元素的字符串数组按流行度排序并生成计数对象数组?
Hey there! Let's walk through how to solve this problem—turning your array of fruits into a sorted list of objects with counts, ordered by popularity (most frequent first). Here's a step-by-step breakdown:
Step 1: Count Occurrences
First, we need to tally up how many times each fruit appears. The reduce method is ideal for this, as it lets us build a count object as we iterate through the array:
const arr = ['banana', 'orange', 'banana', 'apple', 'apple', 'apple', 'orange', 'apple', 'banana']; // Build an object where keys are fruits and values are their counts const countObject = arr.reduce((accumulator, fruit) => { // If the fruit is already in the accumulator, increment its count; otherwise set to 1 accumulator[fruit] = (accumulator[fruit] || 0) + 1; return accumulator; }, {});
This will give us:
{ banana: 3, orange: 2, apple: 4 }
Step 2: Sort by Popularity
Next, we convert the count object into an array of key-value pairs using Object.entries(), then sort this array in descending order based on the count:
// Convert to [fruit, count] pairs and sort by count (highest first) const sortedEntries = Object.entries(countObject).sort((a, b) => b[1] - a[1]);
The result here is:
[ ['apple', 4], ['banana', 3], ['orange', 2] ]
Step 3: Convert to Target Object Format
Finally, we use map() to transform each entry into the object structure you need, with fruit and count properties:
// Map each entry to the desired object shape const newArr = sortedEntries.map(([fruit, count]) => ({ fruit, count }));
Full Working Code
You can chain all these steps together for a concise solution:
const arr = ['banana', 'orange', 'banana', 'apple', 'apple', 'apple', 'orange', 'apple', 'banana']; const newArr = arr .reduce((acc, fruit) => { acc[fruit] = (acc[fruit] || 0) + 1; return acc; }, {}) .entries() .sort((a, b) => b[1] - a[1]) .map(([fruit, count]) => ({ fruit, count })); console.log(newArr); // Output: [ { fruit: 'apple', count: 4 }, { fruit: 'banana', count: 3 }, { fruit: 'orange', count: 2 } ]
Bonus: Handling Ties
If two fruits have the same count, their order will depend on their first occurrence in the original array (modern JavaScript engines use stable sorts). If you want to add a tiebreaker—like sorting alphabetically by fruit name when counts are equal—adjust the comparator function:
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
This will sort fruits with the same count from A-Z.
内容的提问来源于stack exchange,提问作者Kastlej

