Сортировка объекта массива в JavaScript

1

У меня есть массив с несколькими объектами, такими как:

var test = [
 {size: "85A (UK 42A)"},
 {size: "80A (UK 40A)"},
 {size: "105F (UK 48F)"},
 {size: "95E (UK 46E)"},
 {size: "92C (UK 44C)"}
]

Я хочу заказать его по размеру, чтобы порядок стал таким, как показано ниже.

var test = [
 {size: "80A (UK 40A)"}
 {size: "85A (UK 42A)"},
 {size: "92C (UK 44C)"}
 {size: "95E (UK 46E)"},
 {size: "105F (UK 48F)"}
]

Я использовал это, но это возвращает мне массив ниже:

function sorting(json_object, key_to_sort_by) {
 function sortByKey(a, b) {
   var x = a[key_to_sort_by];
   var y = b[key_to_sort_by];
   return ((x < y) ? -1 : ((x > y) ? 1 : 0));
 }

 json_object.sort(sortByKey);
}


var test = [
 {size: "105F (UK 48F)"},
 {size: "80A (UK 40A)"}
 {size: "85A (UK 42A)"},
 {size: "92C (UK 44C)"}
 {size: "95E (UK 46E)"}
]
Теги:
arrays
sorting

3 ответа

2

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

var test = [{ size: "105F (UK 48F)" }, { size: "80A (UK 40A)" }, { size: "85A (UK  2A)" }, { size: "92C (UK 44C)" }, { size: "80B (UK 40B)" }, { size: "80C (UK 40C)" }, { size: "95E (UK 46E)" }];

test.sort(function (a, b) {
    function getV(s) { return s.match(/^(\d+)(\w+)/); }
    var aa = getV(a.size),
        bb = getV(b.size);
    return aa[1] - bb[1] || aa[2].localeCompare(bb[2]);
});

console.log(test);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Для огромных наборов данных вы можете использовать сортировку с картой, потому что

Функция compareFunction может вызываться несколько раз для каждого элемента массива. В зависимости от свойства compareFunction это может привести к высоким накладным расходам. Чем больше работает compareFunction, тем больше элементов для сортировки, тем более разумным может быть использование карты для сортировки. Идея состоит в том, чтобы один раз пройти массив, чтобы извлечь фактические значения, используемые для сортировки во временный массив, отсортировать временный массив и затем пройти временный массив для достижения правильного порядка.

// the array to be sorted
var list = [{ size: "105F (UK 48F)" }, { size: "80A (UK 40A)" }, { size: "85A (UK  2A)" }, { size: "92C (UK 44C)" }, { size: "80B (UK 40B)" }, { size: "80C (UK 40C)" }, { size: "95E (UK 46E)" }];

// temporary array holds objects with position and sort-value
var mapped = list.map(function(el, i) {
    var temp = el.size.match(/^(\d+)(\w+)/);
    return { index: i, number: +temp[1], string: temp[2] || '' };
});

// sorting the mapped array containing the reduced values
mapped.sort(function(a, b) {
    return a.number - b.number || a.string.localeCompare(b.string);
});

// container for the resulting order
var result = mapped.map(function(el){
    return list[el.index];
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
  • 0
    Разве функция не вызывается для каждой пары элементов? Разве это не значит, что вы воссоздаете getN на каждой итерации?
  • 0
    правильно, вы будете использовать сортировку с картой, где карта содержит значения для сортировки, или просто тратить новое свойство на каждый объект, или использовать хэш-таблицу для значений в зависимости от размера массива для сортировки. для небольшого набора оптимизация не требуется.
Показать ещё 1 комментарий
1

По умолчанию сортировка сортирует строки по кодовой точке Unicode. Вы хотите выделить что-то числовое для сортировки, а затем превратить это в число и использовать для сравнения. Что-то вроде этого должно работать...

let sizes = [
    {size: "85A (UK 42A)"},
    {size: "80A (UK 40A)"},
    {size: "105F (UK 48F)"},
    {size: "95E (UK 46E)"},
    {size: "92C (UK 44C)"},
    {size: "80B (UK 40B)"},
];

sizes.sort(function(a, b) {

    var sizeA = a.size.split(' ')[0];
    var sizeB = b.size.split(' ')[0];

    let aInt = parseInt(sizeA);
    let bInt = parseInt(sizeB);
    
    // If the same number, we can just compare the strings
    // since the numeric characters will be equal.
    if (aInt === bInt) {
       return sizeA.localeCompare(sizeB);
    }

    // If not equal, compare the numbers.
    return aInt - bInt;
});

// For snippet.
console.log(sizes);

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

  • 0
    Предполагая, что это на самом деле может быть сложнее, чем кажется на первый взгляд, если вы хотите впоследствии отсортировать по буквам, если числа совпадают?
  • 0
    Да. Если числа совпадают, я тоже хочу отсортировать по буквам.
0

 var test = [
 {size: "85A (UK 42A)"},
 {size: "80A (UK 40A)"},
 {size: "105F (UK 48F)"},
 {size: "95E (UK 46E)"},
 {size: "92C (UK 44C)"}
]

var sorted=test.sort(function(a, b) {
	            return parseInt(a['size'].split(' ')[0])-parseInt(b['size'].split('(')[0]);
	          })
console.log(sorted);           

Ещё вопросы

Сообщество Overcoder
Наверх
Меню