问题描述
对于此CodeWars challenge,其想法是按元素的出现频率对数组进行排序-从发生最多的事件到发生最少的事件。所以
solve([2,3,5,7,9,7]) = [3,2,9]
我要做的是将数组变成字符串,创建频率图,将映射中的项推入排序后的数组,然后将值从排序后的数组推入最终数组。
function solve(arr){
let myString = JSON.stringify(arr).split('');
let newArr = String(myString).replace(/[[,]/gi,'').replace(/]/,'').split('');
let map = {};
let sortedArr = [];
let stringArray = [];
let finalArray = [];
//create frequency map
newArr.forEach((value,index) => {
if (!map[value]) {
map[value] = 0;
}
map[value] += 1;
})
//sort array of elements by frequency
for (let key in map) {
sortedArr.push([key,map[key]])
}
sortedArr = sortedArr.sort((a,b) => b[1] - a[1]);
for (let i = 0; i < sortedArr.length; i++) {
stringArray.push((sortedArr[i][0].repeat(sortedArr[i][1])).split(''));
}
//make frequency array values numerical
for (let i = 0; i < stringArray.length; i++) {
let smallArray = stringArray[i];
for (let j = 0; j < smallArray.length; j++) {
finalArray.push(Number(smallArray[j]));
}
}
return finalArray;
}
console.log(solve([1,1,6,8,1]));
我的代码可用于基本测试,但所有随机测试均未通过,据我所知,CodeWars不会为失败的随机测试提供输入-因此我不知道为什么我的代码失败。
请随时重构。
解决方法
您可以首先使用reduce
方法创建一个对象,其中值是该特定数字的频率,然后使用sort
方法首先按频率排序(如果两个数字具有相同的频率)然后您可以按数字排序。
function solve(data) {
const freq = data.reduce((r,e) => {
if (!r[e]) r[e] = 1;
else r[e]++;
return r;
},{})
return [...data].sort((a,b) => {
return freq[b] - freq[a] || a - b
})
}
console.log(solve([1,2,3,5,1,6,8,9,1]))
console.log(solve([2,7,7]))