Строки сортировки javascript, начинающиеся с числа, не работают

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

например.:

{ value: "10 items", value: "5 items", value: "100 items", value: "20 items" }

Я хочу сделать это по возрастанию, поэтому оно становится:

5 пунктов 10 предметов 20 предметов 100 предметов

Я пытался использовать:

data.sort((a, b) => a > b ? 1 : -1).map((a) => { return a;}

Но это все равно показывает это как:

10 предметов 100 предметов 20 предметов 5 пунктов

При сортировке строк старайтесь использовать localeCompare, чтобы правильно упорядочить их. Итак data.sort((a,b) => a.localeCompare(b)). Кроме того, ваш пример объекта находится в недопустимом объекте, просто распечатайте там массив. Вы даже не можете разобраться в этом, это очень сбивает с толку.

somethinghere 15.05.2024 12:00

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

Ivar 15.05.2024 12:03
Поведение ключевого слова "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) для оценки ваших знаний,...
1
2
96
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Вам нужно сравнить первые части ваших строк в числовом виде, поэтому мы разделяем их, получаем первый элемент, преобразуем их в int, а затем можем сравнить. См. ниже:

let data = [ "10 items", "5 items", "100 items", "20 items" ];
data.sort((a, b) => {
    let x = parseInt(a.split(" ")[0]);
    let y = parseInt(b.split(" ")[0]);
    if (x === y) {
        return 0;
    } else {
        return x > y ? 1 : -1;
    }
});
console.info(data);

Обратите внимание, что я переосмыслил ваш ввод, поскольку тот, который вы дали, был явно неправильным, поскольку повторение одного и того же ключа внутри объекта (value) в этом случае недействительно.

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

udarts 15.05.2024 13:19

Вы можете извлечь числа с помощью s.slice(0, s.indexOf(' ') и сравнить их:

let data = [ "10 items", "5 items", "100 items", "20 items" ];
const getNum = s => s.slice(0, s.indexOf(' '));
data.sort((a, b) => (a = getNum(a), b = getNum(b), a-b));
console.info(data);

Если вы хотите ускориться, вы можете сначала сравнить длину чисел, а затем сравнить их посимвольно, если длина равна:

` Chrome/124
-----------------------------------------------------
Alexander      ■ 1.00x | x1000000 223 245 256 304 317
Lajos Arpad      1.69x | x1000000 376 407 426 433 446
Peter Seliger   99.10x |   x10000 221 235 238 247 271
----------------------------------------------------- `

Открыта детская площадка

let data = [ "10 items", "5 items", "100 items", "20 items" ];

// @benchmark Alexander
data.toSorted((a, b) => {
  a = a.slice(0, a.indexOf(' ')), b = b.slice(0, b.indexOf(' '));
  if (a.length > b.length) return 1;
  if (a.length < b.length) return -1;
  for(let i = 0;i < a.length;i++){
    if (a[i] > b[i]) return 1;
    if (a[i] < b[i]) return -1;
  }
  return 0;
});

// @benchmark Peter Seliger
data.toSorted((a, b) => a.localeCompare(b, undefined, { numeric: true }));

// @benchmark Lajos Arpad
data.toSorted((a, b) => {
    let x = parseInt(a.split(" ")[0]);
    let y = parseInt(b.split(" ")[0]);
    if (x === y) {
        return 0;
    } else {
        return x > y ? 1 : -1;
    }
});

/*@skip*/ fetch('https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js').then(r => r.text().then(eval));

Как упоминалось в комментарии @somethinghere, вы можете использовать localeCompare для сортировки числовых данных.

const data = [{ value: "10 items" },
              { value: "5 items"},
              {value: "100 items"},
              {value: "20 items"}
    ];
const result = data.sort((a, b) => a.value.localeCompare(b.value,undefined,{numeric:true}));
console.info(result );

console.info(
  Object
    .values({
      value1: "10 items",
      value2: "5 items",
      value3: "100 items",
      value4: "20 items",
      value5: "20 facts",
    })
    .sort((a, b) =>
      a.localeCompare(b, undefined, { numeric: true })
    )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

И если ОП хочет отсортировать массив одинаково структурированных объектов, приведенное выше решение тоже немного меняется...

console.info(
  [{
    value: '10 items',
  }, {
    value: '5 items',
  }, {
    value: '100 items',
  }, {
    value: '20 items',
  }, {
    value: '20 facts',
  }]
  .sort((a, b) =>
    a.value.localeCompare(b.value, undefined, { numeric: true })
  )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

хотя чертовски медленно...

Alexander Nenashev 15.05.2024 14:29

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

const data = ["10 items", "5 items", "100 items", "20 items"];

const lookup = data.reduce((m, k) =>
  m.set(k, +k.slice(0, k.indexOf(' '))), new Map);

// @benchmark Mr. Polywhirl
data.toSorted((a, b) => lookup.get(a) - lookup.get(b));

// @benchmark Alexander
data.toSorted((a, b) => {
  a = a.slice(0, a.indexOf(' ')), b = b.slice(0, b.indexOf(' '));
  if (a.length > b.length) return 1;
  if (a.length < b.length) return -1;
  for (let i = 0; i < a.length; i++) {
    if (a[i] > b[i]) return 1;
    if (a[i] < b[i]) return -1;
  }
  return 0;
});

/* @skip */ fetch('https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js').then(r => r.text().then(eval));

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