Найти число в массиве, который ближе всего к заданному числу

У меня есть массив целых чисел в javascript, [5,10,15,20,25,30,35] когда задано число x, как я могу найти элемент в массиве, который ближе всего к этому числу?

Если число превышает значение, но меньше, чем на полпути к следующему числу, я бы выбрал меньшее значение, если бы оно было на полпути к следующему числу, я бы выбрал большее число.

Например, 7 вернет 5, но 8 вернется 10. Как я могу это сделать? Любая помощь или советы будут оценены. Я искал и не могу найти решение. Я уверен, что это обычное явление.

Ответы

Ответ 1

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

Если список не всегда сортируется, перейдите в список, отслеживающий наибольшее число <= номер цели и наименьшее число >= целевой номер. Верните ту, которая ближе всего к цели.

В любом решении вам нужно будет решить, какую сторону поддержать, если, например, вы ищете 2 в [1, 3].

Ответ 2

function getClosest(array, target) {
    var tuples = _.map(array, function(val) {
        return [val, Math.abs(val - target)];
    });
    return _.reduce(tuples, function(memo, val) {
        return (memo[1] < val[1]) ? memo : val;
    }, [-1, 999])[0];
}

Если используется функциональный подход, вы можете сопоставить набор с кортежами (значение, расстояние), а затем уменьшить этот набор кортежей в кортеж с наименьшим расстоянием. Мы возвращаем значение в этом кортеже.

Объяснить использование _.map. Вы сопоставляете все значения в вашем массиве с новыми значениями, и функция возвращает массив новых значений. В этом случае массив кортежей.

Объяснить использование _.reduce. Вы уменьшаете массив до одного значения. Вы передаете массив и памятку. Меморандум - это ваш "счетчик" при перемещении по массиву. В этом случае мы проверяем, ближе ли текущий кортеж, а затем записка, и если да, сделайте это запиской. Затем мы возвращаем записку в конце.

Фрагмент кода выше полагается на underscore.js, чтобы удалить nitty gritty функционального стиля javascript

Ответ 3

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

Встроенный Array.prototype.sort() может использовать функцию сравнения, которая будет вызываться для пар значений из массива. Затем ключ просто перейти в функции сравнения, которая сравнивает два значения в зависимости от их расстояния от опорного значения х.

let x = 8;
let array = [5, 10, 15, 20, 25, 30, 35];
let closest = array.sort( (a, b) => Math.abs(x - a) - Math.abs(x - b) )[0];

Смотрите эту простую демонстрацию .

Ответ 4

Создайте временный массив того же размера, что и ваш исходный массив, и заполните его различиями между вашим x и элементом массива.

Например, пусть временный массив будет temp [], а ваш исходный массив - []:

temp[i]=Math.abs(x-a[i]);

Затем верните индекс минимального значения в temp [] пользователю.

Ответ 5

Предполагая, что массив отсортирован, пройдите через каждую соседнюю пару целых чисел в массиве. Для каждой пары (скажем, "5 и 10" или "20 и 25" ) проверьте, если x находится между ними, и если да, верните, какой бы ни был ближе к x (с уклоном к нижнему).

Вам также понадобится специальный случай, когда x меньше первого числа (верните первое число) или больше последнего числа (верните последний номер).

Если массив не отсортирован, сначала выберите его.

Ответ 6

Я создал свою собственную функцию, так как не мог найти того, что соответствует моим запросам.

    function closest_number(quantities, number, closest_factor)
    {
        if (closest_factor == 'ceil')
        {
            quantities.sort(function(a, b)
                {
                    return a - b
                }
            );

            for (var i = 0; i < quantities.length; i++)
            {
                if (quantities[i] >= number)
                {
                    return quantities[i];
                }

                last_value = quantities[i];
            }

            return last_value;
        }
        else if (closest_factor == 'floor')
        {
            quantities.sort(function(a, b)
                {
                    return a - b
                }
            );

            min_value = quantities[0];

            for (var i = 0; i < quantities.length; i++)
            {
                if (number == quantities[i])
                {
                    return number;
                }
                else if (quantities[i] < number)
                {
                    min_value = quantities[i];
                }
                else if(quantities[i] > number)
                {
                    return min_value;
                }           
            }

            return min_value;
        }
        else
        {
            return false;
        }
    };