0

For this CodeWars challenge, the idea is to sort the array by frequency of elements - from most occurring to least occurring. So

solve([2,3,5,3,7,9,5,3,7]) = [3,3,3,5,5,7,7,2,9]

What I've done is turned the array into a string, created a frequency map, pushed the items from that map into a sorted array, and then pushed the numerical values from the sorted array into a final array.

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,2,3,0,5,0,1,6,8,8,6,9,1]));

My code is working for the basic tests, but is failing all random tests, and, as far as I know, CodeWars doesn't provide inputs for the failed random tests - so I don't have an idea of knowing why my code is failing.

Please feel free to re-factor as well.

3
  • I would not do it with strings. I'd make an object that counted each value, then sort with that object as a reference. Commented Aug 19, 2020 at 15:55
  • 3
    First thing that stands out is that your approach doesn't handle multi digit numbers correctly, for example an array like [21, 22] will become [2,1,2,2]. Commented Aug 19, 2020 at 16:00
  • 1
    Instead of all that stringify-ing and replace-ing, you can just map the array, eg: let newArr = arr.map(e => e.toString()) Commented Aug 19, 2020 at 16:01

1 Answer 1

4

You could first use reduce method to create an object where the value is the frequency of that specific number and then use the sort method to first sort by frequency and if two numbers have the same frequency then you can sort by number.

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, 0, 5, 0, 1, 6, 8, 8, 6, 9, 1]))
console.log(solve([2, 3, 5, 3, 7, 9, 5, 3, 7]))

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.