Как отсортировать массив по ближайшему числу

Я пытаюсь отсортировать массив по ближайшему элементу к определенному числу

Следующее решение не работает во всех случаях без причины

let array = [{"price":"6850000"},{"price":"6692301"},{"price":"6880000"},{"price":"6735100"},{"price":"6708900"},{"price":"7000000"}]

var price = 6692300
const closestArray = array.sort((a, b) => {
  if (Math.abs(b.price - price) > Math.abs(a.price - price)) {
      return b.price
  } else {
      return a.price
  }
})

console.info(closestArray)

IT работает с этим примером:

let array = [401,402,400,478,421,432]

var price = 400
const closestArray = array.sort((a, b) => {
    if (Math.abs(b - price) < Math.abs(a - price)) {
        return b
    } 
})

console.info(closestArray);

Когда вы говорите «ближайший», вместо этого вы должны использовать Math.abs(), чтобы сравнить разницу.

Terry 19.12.2020 17:38

...не во всех случаях работает" - А такие случаи есть?

Andreas 19.12.2020 17:40

@Terry Терри, я только что попробовал использовать Math.abs(), и это дает мне такой же неправильный вид

BOUK. 19.12.2020 17:40
return -1 вместо return b.price и return 1 вместо return a.price
Aplet123 19.12.2020 17:41

Функция сравнения должна возвращать «меньше нуля», «ноль» или «больше нуля».

Andreas 19.12.2020 17:43

Ответ @Aplet123 - это то, что вы ищете

Maher Fattouh 19.12.2020 17:45
Поведение ключевого слова "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
6
145
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

В обоих случаях вы возвращаете положительное число. То есть в обоих случаях вы возвращаетесь >0. Это означает, что ваш код действительно делает:

  if (Math.abs(b.price - price) > Math.abs(a.price - price)) {
      sort b before a
  } else {
      sort b before a
  }

По сути, ваше утверждение if ничего не делает.

То, что вы действительно хотите, это:

  if (Math.abs(b.price - price) > Math.abs(a.price - price)) {
      return 1
  } else {
      return -1
  }

или

  if (Math.abs(b.price - price) > Math.abs(a.price - price)) {
      return -1
  } else {
      return 1
  }

в зависимости от погоды вы хотите отсортировать по возрастанию или по убыванию.

Еще лучше, что вы действительно должны делать:

return Math.abs(b.price - price) - Math.abs(a.price - price)

или

return Math.abs(a.price - price) - Math.abs(b.price - price)

Лучше все же вы действительно должны делать" - Почему? Что не так с if...else...

Andreas 19.12.2020 17:49

Если .. else не обрабатывает нулевой регистр. Минус может возвращать > 0, < 0 или 0, что даст вам более предсказуемую и стабильную сортировку (не переключает связи без необходимости). Даже если добавить и else if. Арифметический код меньше, более математически правилен, его легче читать и понимать, и он использует меньше инструкций ЦП (одна единственная инструкция вместо вычитания, сравнения, ветвления, что хуже с else...if, потому что это будет делаться дважды), поэтому он быстрее

slebetman 19.12.2020 17:53

Нулевой случай да. Остальное неверно (математика та же) или в случае JS не имеет значения (циклы процессора, когда между инструкцией и фактическим процессором есть несколько слоев программного обеспечения). Но, тем не менее, вы можете добавить в свой ответ хотя бы нулевой случай в качестве объяснения «лучшего» способа.

Andreas 19.12.2020 18:37

То, что вы делали, заключалось в том, что вы возвращали цену, но эта цена всегда была больше 0, что должно возвращать число больше 0, только если второе или b должно стоять первым.

let array = [{"price":"6850000"},{"price":"6692301"},{"price":"6880000"},{"price":"6735100"},{"price":"6708900"},{"price":"7000000"}];

var price = 6692300;
const closestArray = array.sort((a, b) => {
  if (Math.abs(b.price - price) < Math.abs(a.price - price)) {
      return 1;
  } else if (Math.abs(b.price - price) > Math.abs(a.price - price)) {
      return -1;
  }
  return 0; // because they are equal in value and should have equal ordering
})

console.info(closestArray);

Я верю, что это работает.

let array = [{"price":"6850000"},{"price":"6692301"},{"price":"6880000"},{"price":"6735100"},{"price":"6708900"},{"price":"7000000"}]

var price = 6692300;
const closestArray = array.sort((a, b) => {
    const distOne = a.price - price;
    const distTwo = b.price - price;
    return Math.abs(distOne) - Math.abs(distTwo);
});

console.info(closestArray);

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