Я пытаюсь отсортировать объект строк, который будет работать с обычной функцией сортировки, но мне не удается заставить его работать, поскольку строки начинаются с числа:
например.:
{ 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 пунктов
Объекты не могут иметь повторяющиеся ключи, поэтому в этом нет особого смысла. У объектов также нет функции .sort, поэтому data.sort() должна выдавать ошибку.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вам нужно сравнить первые части ваших строк в числовом виде, поэтому мы разделяем их, получаем первый элемент, преобразуем их в 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) в этом случае недействительно.
Мне действительно пришлось изменить некоторые вещи, но у меня это работает.
Вы можете извлечь числа с помощью 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 );sort все значения объекта.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; }хотя чертовски медленно...
Если вам нужна еще более быстрая сортировка, вы можете создать поиск 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));
При сортировке строк старайтесь использовать
localeCompare, чтобы правильно упорядочить их. Итакdata.sort((a,b) => a.localeCompare(b)). Кроме того, ваш пример объекта находится в недопустимом объекте, просто распечатайте там массив. Вы даже не можете разобраться в этом, это очень сбивает с толку.