JS вывод параметров объекта по значению ключа
Реализовываю на js алгоритм сортировки подсчетом. Если кратко алгоритм: У нас есть массив чисел(int/float), и мы подсчитываем кол-во одинаковых элементов, а потом просто выводим их в нужном порядке. Пример: Массив - 5, 2, 4, 1, 7, 3, 2, 3, 5, 9, -2, 0, 5, 2 Подсчитали:
-2: 1
0: 1
1: 1
2: 3
3: 2
4: 1
5: 3
7: 1
9: 1
и выводим: -2, 0, 1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 7, 9
Проблема в том, что в js нету такого как массив с ключами. Но есть объекты.
Как названия параметров я использую значения которые надо отсортировать. Но столкнулся с проблемой что js очень странно сохраняет порядок параметров объекта: сначала положительные числа от меньших к большим, а после них - отрицательные, но уже от больших к меньшим. Вот пример:
0: 1
1: 1
2: 2
3: 1
4: 1
5: 1
-2: 1
-3: 3
-4: 1
-5: 3
Подозреваю что js просто сортирует их как символьные строки.
Я знаю что можно сделать из объекта массив массивов с элементами значение-ключ, который можно упорядочить, но это дополнительная сортировка которая значительно повлияет на результат. Скажите пожалуйста, можно ли как-то по дефолту указать чтобы параметры были нормально отсортированы, или возможно как-то по другому их выводить. Спасибо
Обновлено: Положительные числа выводятся в нужном порядке, а отрицательные - в таком, в каком они создавались. Я навел пример из консоли браузера, в ней они сортировались, но не отображался реальный порядок.
Ответы (3 шт):
А такой алгоритм устроит (если я правильно понял)?
arr = [5, 2, 4, 1, 7, 3, 2, 3, 5, 9, -2, 0, 5, 2,];
// найти минимальное значение в массиве
min = arr[0];
for (let value of arr) {
min = value < min ? value : min
}
// подсчитать кол-во уникальных элементов в массиве
counts = [];
for (let value of arr) {
counts[value - min] = counts[value - min] ? counts[value - min] + 1 : 1
}
// отсортировать значения
res = [];
for (let index in counts) {
const value = parseInt(index) + min;
for (let i = 0; i < counts[index]; i ++)
res.push(value);
}
console.log(res);
// Генератор случайных значений
const random = ()=>Math.trunc(10*Math.random()-5)/4;
// Массив со значениями
const array = new Array(100).fill(0).map(random);
// Вывод массива значений
console.log('array', JSON.stringify(array).replace(/.{57,62},/g,'$&\n'));
// Счетчик значений
const counter = v => [v, array.filter(n=>n==v).length];
// Формируем объект
const obj = Object.fromEntries([...(new Set(array))].map(counter));
// Вывод объекта до сортировки
console.log('obj', JSON.stringify(obj,null,2)
.replace(/\"([0-9.-]+)\"/g,(...[,m])=>`[${m}]`.padEnd(7)));
// Сортируем элементы объекта по ключам
const result = Object.entries(obj).sort(([a],[b])=>Math.sign(a-b))
// В результате бyдет массив из пар ключ-значение:
// Можем выводить их построчно
for(const [key,val] of result){
console.log(`result[${(''+key+']').padEnd(6)} = ${val};`);
}
Заметьте, результаты легко сортируются с ключами с плавающей точкой.
const arr = [- 5, 2, 4, 1, 7, 3, 2, 3, 4.1, 5, 9, -2, 0,Math.PI, 5, 2];
const donor = [...arr];
const result = [];
let n = Math.min(...donor);
while(n<Infinity){
result.push(n);
donor.splice(donor.indexOf(n),1);
n = Math.min(...donor);
}
console.log(result);