Функция Javascript не работает с двузначными числами

Учитывая массив чисел, мне нужно найти число с наибольшей частотой и вернуть его. Если есть два или более числа с одинаковой самой высокой частотой, мне нужно вернуть самое большое число.

Ниже приведен код, который я написал.

const numbers = [1, 2, 3, 4, 5, 4, 3, 4, 3, 2, 1, 6, 7, 5];
const numArr = [12, 20, 5, 4, 10, 10, 10, 5, 4, 5, 3, 2];

function frequency(array) {
    let object = {}
    let maxCount = 0;
    let result = 0;

    for (let num of array) {
        if (object.hasOwnProperty(num)) {
            object[num] = object[num] + 1;
        }
        else object[num] = 1;
    }
    console.info(object)
    let entry = Object.entries(object)
    for (const [key, val] of entry) {
        if (maxCount < val) {
            maxCount = val;
            result = key;
        }
    }

    for (const [key, val] of entry) {
        result = maxCount === val && key > result ? key : result;

    }
    return [result, maxCount];
}

const [res, count] = frequency(numArr);
console.info(`number with highest freq: ${res}\nfrequency: ${count}`)

Функция frequency работает с массивами, содержащими однозначные числа (например, numbers). Но он не дает правильного вывода с массивами, содержащими двузначные числа (например, numArr)

Приведенный выше код должен выводить 10 как число с самой высокой частотой и 3 как его частоту. Но он выводит 5 и 3 соответственно. Почему это? Связано ли это со значениями ASCII? Спасибо за ваше время.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
95
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Ключи уже отсортированы, и если вы хотите получить наивысший «результат», вам нужно изменить maxCount < val на maxCount <= val,, где более высокий ключ заменит более низкий ключ при одинаковых частотах.

Кроме того, вам не нужна последняя петля. Это ничего не делает, кроме как портит ваш код.

const numbers = [1, 2, 3, 4, 5, 4, 3, 4, 3, 2, 1, 6, 7, 5];
const numArr = [12, 20, 5, 4, 10, 10, 10, 5, 4, 5, 3, 2];

function frequency(array) {
    let object = {}
    let maxCount = 0;
    let result = 0;

    for (let num of array) {
        if (object.hasOwnProperty(num)) {
            object[num] = object[num] + 1;
        }
        else object[num] = 1;
    }
    console.info(object)
    let entry = Object.entries(object)
    for (const [key, val] of entry) {
        // if (maxCount < val) {
        if (maxCount <= val) {
            maxCount = val;
            result = key;
        }
    }

    /*
    for (const [key, val] of entry) {
        result = maxCount === val && key > result ? key : result;

    }*/
    return [result, maxCount];
}

const [res, count] = frequency(numArr);
console.info(`number with highest freq: ${res}\nfrequency: ${count}`)

Наконец, вы сможете решить эту проблему, используя только один цикл.

const numbers = [1, 2, 3, 4, 5, 4, 3, 4, 3, 2, 1, 6, 7, 5];
const numArr = [12, 20, 5, 4, 10, 10, 10, 5, 4, 5, 3, 2];

function frequency(array) {
    let object = {};
    let hasHigherFrequency = false, hasEqualFrequencyButHigherValue = false;
    let highestFrequency = {
      res: 0,
      count: 0
    };

    for (let num of array) {
        if (object.hasOwnProperty(num)) {
            object[num] = object[num] + 1;
        }
        else object[num] = 1;
        
        hasHigherFrequency = object[num] > highestFrequency.count;
        hasEqualFrequencyButHigherValue = object[num] == highestFrequency.count && num > highestFrequency.res;
        
        if (hasHigherFrequency || hasEqualFrequencyButHigherValue) {
          highestFrequency = {res: num, count: object[num]};
        }
    }
    
    console.info(object);

    return highestFrequency;
}

const {res, count} = frequency(numArr);
console.info(`number with highest freq: ${res}\nfrequency: ${count}`)

Ключи в объектах всегда представляют собой строки или символы, а не числа. Для большей части вашего кода это нормально, но это проблема в двух циклах for-of над Object.entries, поскольку key будет строка, и в конечном итоге вы установите result в строку. Во втором цикле key > result — это сравнение строк, при котором выполняется поразрядное, а не числовое сравнение.

Вместо использования объекта для подсчета используйте Map. Map ключи могут быть реальными цифрами. См. статью MDN на Map, чтобы узнать рекомендации о том, когда использовать объекты, а не карты.

const numbers = [1, 2, 3, 4, 5, 4, 3, 4, 3, 2, 1, 6, 7, 5];
const numArr = [12, 20, 5, 4, 10, 10, 10, 5, 4, 5, 3, 2];

function frequency(array) {
    let map = new Map();
    let maxCount = 0;
    let result = 0;

    for (let num of array) {
        const value = map.get(num) ?? 0;
        map.set(num, value + 1);
    }
    console.info([...map]);
    for (const [key, val] of map) {
        if (maxCount < val) {
            maxCount = val;
            result = key;
        }
    }

    for (const [key, val] of map) {
        result = maxCount === val && key > result ? key : result;
    }
    return [result, maxCount];
}

const [res, count] = frequency(numArr);
console.info(`number with highest freq: ${res}\nfrequency: ${count}`);

Здесь понадобится всего 1 петля, просто сравнивайте с максимумом, пока собираете отсчеты. Таким образом, вам также не нужно заботиться о преобразовании числа/строки для результата:

const numArr = [12, 20, 5, 4, 10, 10, 10, 5, 4, 5, 3, 2];

function frequency(array) {
    const object = {};
    let maxCount = 0, result = 0;

    for (const num of array) {
        const val = object[num] = (object[num] ?? 0) + 1;
        if (maxCount < val) maxCount = val, result = num;
        else if (maxCount === val && result < num) result = num;
    }
    return [result, maxCount];
}

const [res, count] = frequency(numArr.sort().reverse());
console.info(`number with highest freq: ${res}\nfrequency: ${count}`)

Если вы запустите frequency(numArr.sort().reverse()), он вернет 5 в качестве res. Также нужно учитывать num.

Rickard Elimää 07.04.2024 13:30

@RickardElimää, спасибо, исправлено, я пропустил это в вопросе, думал, что требование проще

Alexander Nenashev 07.04.2024 13:35

Теперь вы заслужили мой +1. :D

Rickard Elimää 07.04.2024 13:36

Другие вопросы по теме

Похожие вопросы

VueUse useIntersectionObserver и rootMargin, срабатывающий задолго до того, как элемент окажется в пределах диапазона
Невозможно подключиться к веб-сокету из Javascript, даже если я могу с помощью Postman
Необнаруженная ошибка: не удалось найти соответствующий маршрут при перенаправлении на страницу /login после выхода из системы
Нажатие кнопки согласия с кукловодом
Ограничить диапазон от начала до конца при проверке Joi
Как предотвратить создание новых текстовых узлов после нажатия клавиши «Ввод» в элементе contenteditable?
Надежно сжимайте строку из единиц и нулей в строку меньшего размера и преобразуйте ее обратно в точно такую ​​же строку. Каждый раз
Как установить примечание к ячейке Google Таблиц на основе значения ячейки, которое начинается со знака плюс
Поиск Mongoose по вложенному объекту модели
Автозаполнение JQuery из БД при весенней загрузке и Thymeleaf