Существует массив, элементы которого являются одинаковыми элементами в случайном порядке. Я хочу переупорядочить массив так, чтобы сначала отображались элементы с высокой частотой, а затем элементы с самой низкой частотой.

В принципе, какой код должен возвращать результат ниже?

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];

Заранее большое спасибо!

-1
J.Ko 8 Окт 2020 в 14:26

5 ответов

Лучший ответ

Вычислите частоту, а затем отсортируйте массив по частоте:

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);
2
Rahul Bhobe 8 Окт 2020 в 11:52

Вам нужно собрать одинаковые значения, отсортировать по длине и получить плоский массив.

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
Rahul Bhobe 8 Окт 2020 в 11:40

Вы можете собрать карту частот, отсортировать ее и сгенерировать результирующий массив по значению и частоте.

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))
0
Yury Tarabanko 8 Окт 2020 в 11:47
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()
);
0
Peter Seliger 8 Окт 2020 в 13:29

Вы также можете использовать объект, чтобы сохранить, сколько раз появляется каждое число, и отсортировать массив на этой основе.

 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 ]
*/
0
Ketan Ramteke 8 Окт 2020 в 20:04