-1

There is an array whose elements are same items in random order. I want to reorder the array such that items with high frequencies appear first and then the items with the lowest frequencies appear last.

Basically, what would be the code to return the result below?

const a = [1,5,3,3,2,3,4,3,3,2,4,4,4];

const result = [3,3,3,3,3,4,4,4,4,2,2,1,5];

Thanks a lot in advance!

3
  • 2
    This is really bad sample data, as it makes it look like a reverse sort will give the desired result, which is not what the question implies Commented Oct 8, 2020 at 11:30
  • @Nick I edited the sample Commented Oct 8, 2020 at 11:35
  • @RahulBhobe better to let OP edit, to ensure that my comment truly reflects what they meant. Commented Oct 8, 2020 at 11:39

5 Answers 5

3

Calculate the frequency and then sort the array based on the frequency:

let a = [1,5,3,3,2,3,4,3,3,2,4,4,4];

const freq = a.reduce((c, v) => (c[v] = (c[v] || 0) + 1, c), {});

a.sort((x, y) => freq[y]-freq[x] || y-x);

console.log(a);

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

1 Comment

You can compute frequency using reduce: const frequency = a.reduce((c, v) => (c[v] = (c[v] || 0) + 1, c), {});
2

You need to collect same values, sort by length and get a flat array.

const
   array = [1,5,3,3,2,3,4,3,3,2,4,4,4],
   result = array
       .reduce((r, v) => {
           const temp = r.find(([w]) => v === w);
           if (temp) temp.push(v);
           else r.push([v]);
           return r;
       }, [])
       .sort((a, b) => b.length - a.length)
       .flat();

console.log(...result);

1 Comment

sort((a, b) => b.length-a.length || b-a) or sort((a, b) => b.length-a.length || a-b) might be better?
0

You can collect a frequency map, sort it, and generate resulting array by value and frequency.

const a = [1, 2, 3, 4, 3, 3, 2, 4, 4, 4, 5];

const result = [...a.reduce((freqs, item) => freqs.set(item, (freqs.get(item) || 0) + 1), new Map).entries()]
  .sort(([, a], [, b]) => b - a)
  .flatMap(([value, length]) => Array.from({length}).fill(value))

console.log(JSON.stringify(result))

Comments

0

function compareValues(a, b) {
  return (a.localeCompare && b.localeCompare)
    ? a.localeCompare(b)
    : ((a < b && -1) || (a > b && 1) || 0);
}
function compareValueLists(a, b) {
  return (b.length - a.length) || compareValues(a[0], b[0]);
}

function collectEqualValue(collector, value) {
  const { index, list } = collector;
  let valueList = index[value];

  if (!valueList) {
    valueList = index[value] = [];

    list.push(valueList);
  }
  valueList.push(value);

  return collector;
}
const sampleList = [5, 1, 3, 3, 2, 3, 4, 3, 3, 2, 4, 4, 4];

console.log(
  ...sampleList
    .reduce(collectEqualValue, { index: {}, list: [] }).list
    .sort(compareValueLists)
    .flat()
);

Comments

0

You can also use an object to store how many times each number appears and sort the array on that basis.

 let a = [1, 2, 3, 3, 2, 3, 4, 3, 3, 2, 4, 4, 4];
    
    let obj = {};
    for (num of a) {
      if (obj[num] === undefined) {
        obj[num] = 1;
      } else {
        obj[num] += 1;
      }
    }
    
    Object.keys(obj)
      .sort((a, b) => obj[b] - obj[a])
      .map((key) => Array.from({ length: obj[key] }, () => parseInt(key)))
      .flat();

/*
OUTPUT: [3, 3, 3, 3, 3, 4, 4, 4, 4, 2, 2, 2, 1 ]
*/

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.