Получить ключ ближайшего объекта из объекта, содержащего несколько объектов с числовыми ключами

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

Пример структуры объекта

{
"32.5": [
{
  "key": "value",
  "key": "value"
},
{
  "key": "value",
  "key": "value"
}
],
"34": [
{
  "key": "value",
  "key": "value"
}
],
"35.5": [
{
  "key": "value",
  "key": "value"
}
]
}

Ключи объекта представляют собой строки, поэтому я уже понял, что мне, вероятно, каким-то образом нужно преобразовать ключи объекта в число для сравнения, но я совершенно не понимаю, как связать все это вместе.

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

function getNearest(obj, decimalNumber, below_or_above)

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

Если бы я вызвал getNearest(obj, 33.4, выше), он должен вернуть объект с ключом «34».

Надеюсь, мне удалось как-то объяснить, чтобы все поняли..

Это отправная точка, которую я придумал, но я не знаю, как двигаться дальше

    function getNearest(obj, decimalNumber, above_or_below){
    const keys = [];
    Object.keys(obj).forEach(key =>{
        let numericKey = Number(key);
        keys.push(numericKey);
    })

    //store all numeric keys in array to further process later on
    }
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
1
0
31
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы могли

  • получить ключи от объекта,
  • номера карты,
  • массив сортировки для настройки собственной сортировки объектов (сначала положите 32-битное целое число),
  • найдите значение, проверив, меньше ли оно, чем значение или последний элемент, или если абсолютная дельта фактического и следующего элемента меньше.
 value   below   above
------- ------- -------                
  0     undef    32.5
 31.4   undef    32.5
 32.5    32.5    34
 32.8    32.5    34
 33.4    32.5    34
 34      34      34
 35.1    34      35.5
 35.5    35.5    35.5
 50      35.5    undef

 isAbove false    true

const
    getKey = (object, value, isAbove) => Object
        .keys(object)
        .map(Number)
        .sort((a, b) => a - b)
        .find((v, i, a) => isAbove
            ? v >= value
            : v <= value && (a[i + 1] > value || i + 1 === a.length)
        ),
    data = { 32.5: [{}], 34: [{}], 35.5: [{}] };

console.log('below');
console.log(getKey(data, 0)); // 32.3
console.log(getKey(data, 31.4)); // 32.3
console.log(getKey(data, 32.5)); // 32.3
console.log(getKey(data, 32.8)); // 32.3
console.log(getKey(data, 33.4)); // 34
console.log(getKey(data, 34)); // 34
console.log(getKey(data, 35.1)); // 35.5
console.log(getKey(data, 35.5)); // 35.5
console.log(getKey(data, 100)); // 35.5

console.log('above');
console.log(getKey(data, 0, true)); // 32.3
console.log(getKey(data, 31.4, true)); // 32.3
console.log(getKey(data, 32.5, true)); // 32.3
console.log(getKey(data, 32.8, true)); // 32.3
console.log(getKey(data, 33.4, true)); // 34
console.log(getKey(data, 34, true)); // 34
console.log(getKey(data, 35.1, true)); // 35.5
console.log(getKey(data, 35.5, true)); // 35.5
console.log(getKey(data, 100, true)); // 35.5
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

BitQueen 16.05.2022 20:05

вы хотите получить, если значение ниже или выше? почему бы не проверить возвращаемое значение на соответствие желаемому?

Nina Scholz 16.05.2022 20:10

нет, может быть, я недостаточно хорошо объяснил, мой английский не слишком хорош. Мне нужна функция, которая принимает параметр «выше» или «ниже», а затем получает ближайшее НИЖЕ число, которое я ввожу в функцию, или в другом случае, когда я ввожу «выше» в качестве параметра, получаю ближайшее ВЫШЕ число, которое я поставил в

BitQueen 16.05.2022 20:13

как getNearest (objToFilter, inputNumber, выше_или_ниже))

BitQueen 16.05.2022 20:14

какое значение вы ожидаете, если это невозможно?

Nina Scholz 16.05.2022 20:15

в этом случае я знаю, что всегда будут значения выше или ниже того, что я ввел в функцию, но мой запасной вариант был бы всего 0,00

BitQueen 16.05.2022 20:18

Все вышеперечисленное приводит к undefined.

SSM 16.05.2022 21:03

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

Nina Scholz 16.05.2022 21:04
Ответ принят как подходящий
  • Преобразуйте объект в массив элементов, используя Объект.записи.
  • Переберите объект, используя Array.prototype.map, и преобразуйте строковые ключи в числа, чтобы правильно выполнять сравнения.
  • Отсортируйте массив по ключам, используя Массив.прототип.сортировка.
  • Найдите ключ на основе аргумента pos, используя Array.prototype.find.
  • Наконец, верните значение, соответствующее найденному ключу.

const 
  data = { 32.5: [{ key: "32.5" }], 34: [{ key: "34" }], 35.5: [{ key: "35.5" }] },
  getKey = (obj, target, pos) =>
    Object.entries(obj)
      .map(([k, v]) => [Number(k), v])
      .sort(([a], [b]) => a - b)
      .find(([k], i, a) =>
        pos === "above"
          ? k >= target
          : k <= target && (a[i + 1]?.[0] > target || i === a.length - 1)
      )?.[1];

console.log(getKey(data, 33, "above")); // [{ key: "34" }]
console.log(getKey(data, 33, "below")); // [{ key: "32.5" }]
console.log(getKey(data, 37, "above")); // undefined
console.log(getKey(data, 30, "below")); // undefined

Таблица для справки:

цельниженад
0undefined[{ key: '32.5' }]
31.4undefined[{ key: '32.5' }]
32.5[{ key: '32.5' }][{ key: '34' }]
32.8[{ key: '32.5' }][{ key: '34' }]
33.4[{ key: '32.5' }][{ key: '34' }]
34[{ key: '34' }][{ key: '34' }]
35.1[{ key: '34' }][{ key: '35.5' }]
35.5[{ key: '35.5' }][{ key: '35.5' }]
50[{ key: '35.5' }]undefined

это возвращает первое наименьшее значение, даже если оно больше, но меньше желаемого...

Nina Scholz 16.05.2022 20:47

@NinaScholz Извините, я этого не понял, можете ли вы предоставить тестовый пример, в котором это решение не работает?

SSM 16.05.2022 21:01

пожалуйста, посмотрите на таблицу в моем ответе.

Nina Scholz 16.05.2022 21:05

@NinaScholz Спасибо за указание, я обновил свой ответ. Кстати, в вашей таблице опечатка, 32.3 должно быть 32.5.

SSM 16.05.2022 21:20

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