Вы можете использовать цифру c сопоставление с String#localeCompare
. Это позволит избежать лексикографии c сортировки и даст вам правильную цифру c порядок:
var a = "10";
var b = "2";
console.log( //false - string "10" does not come after "2" because 1 < 2
"a > b:",
a > b
);
console.log( //-1 - `a` comes before `b`
"a.localeCompare(b):",
a.localeCompare(b)
);
console.log( // 1 - `a` comes after `b`
"a.localeCompare(b, undefined, {numeric: true}):",
a.localeCompare(b, undefined, {numeric: true})
);
Обратите внимание, что это работает для строк . Если вы также хотите отсортировать числа, у вас есть два простых варианта:
- Привести числа к строкам, а затем использовать сортировку строк с сортировкой чисел c. Он будет работать так же, и ваш код будет простым.
- Используйте
if
, чтобы проверить, что вы сравниваете, и примените .localeCompare
logi c для строк и другой логики c для чисел.
Оба сработают, но я лично предпочитаю первый, так как он не требует ведения разных дел. Таким образом, использование его в вашем решении дает правильные результаты:
var arr = [{name: "a1", value: 1},{name: "a3", value: 1},{name: "a4", value: 1},{name: "a2", value: 1}];
var arr2 = [{name: "a1", value: 1},{name: "a3", value: 1},{name: "a14", value: 1},{name: "a12", value: 1}];
var arr3 = [{name: "a", value: 3},{name: "a", value: 1},{name: "a", value: 14},{name: "a", value: 12}];
var sort = function (prop, arr) {
prop = prop.split('.');
var len = prop.length;
arr.sort(function (a, b) {var i = 0;
while( i < len ) {
a = a[prop[i]];
b = b[prop[i]];
i++;
}
//cast to string
a = String(a);
b = String(b);
return a.localeCompare(b, undefined, {numeric: true})
});
return arr;
};
arr = sort('name', arr);
arr2 = sort('name', arr2);
console.log(arr); // it's correct
console.log(arr2); // it's correct
arr3 = sort('value', arr3);
console.log(arr3); // it's correct