упорядочить массив javascript путем группировки в соответствии со свойством - PullRequest
2 голосов
/ 27 декабря 2011

Я использую массив объектов json из поискового веб-сервиса для подачи автозаполнения jQuery.ui, где я использую систему категорий для группировки своих объектов по их «семейству»

Алгоритм использует список, в котором группы уже упорядочены, что я не могу сделать в данный момент, поэтому я хотел бы организовать данные на стороне клиента.Так, например, если у меня есть следующий массив:

var resultsArray = [
{"cat": "Category #1", "Id": "10"},
{"cat": "Category #2", "Id": "28"},
{"cat": "Category #1", "Id": "11"},
{"cat": "Category #2", "Id": "21"},
{"cat": "Category #1", "Id": "13"}
];

, я бы хотел вызвать метод resultsArray, чтобы я вернулся

resultsArray = [
{"cat": "Category #1", "Id": "10"},
{"cat": "Category #1", "Id": "11"},
{"cat": "Category #1", "Id": "13"},
{"cat": "Category #2", "Id": "28"},
{"cat": "Category #2", "Id": "21"}
];

, группируя по свойству cat, сохраняя при этомсуществующий порядок.

Сначала я попытался использовать метод сортировки в массиве, возвращая позиции в массиве, в которых будет найдено значение, по которому я пытаюсь сгруппировать (предположим, что acs.groupBy содержит имясвойства группировки:

items.sort(function(a, b) {
    var aValue = a[acs.groupBy],
    bValue = b[acs.groupBy];
    var indexOfAValue = 0; // should be sthing like items.indexWhere(item[acs.groupBy] === aValue)
    var indexOfBValue = 0; // same thing
    return indexOfAValue - indexOfBValue;
});

с indexOfAValue будет первой позицией в массиве, где будет найдено свойство группировки для A, но я не могу найти метод для получения и кэширования этого значения просто (массивindexOf соответствует целому объекту.) Любая идея, чтобы получить это?


РЕДАКТИРОВАТЬ

Похоже, я дал неправильный пример :) Я не хочусортировать категории.Если Категория # 2 происходит раньше, чем Категория # 1, я хочу сохранить эту информацию, чтобы

var resultsArray = [
    {"cat": "Category #3", "Id": "39"},
    {"cat": "Category #2", "Id": "28"},
    {"cat": "Category #1", "Id": "11"},
    {"cat": "Category #2", "Id": "21"},
    {"cat": "Category #1", "Id": "18"}
]

стал (обратите внимание, что хотя я сгруппировал элементы по их категории, я не изменил порядок вкакие категории встречаются, и я не менял порядок элементов внутри групп в соответствии с их идентификатором)

var resultsArray = [
    {"cat": "Category #3", "Id": "39"},
    {"cat": "Category #2", "Id": "28"},
    {"cat": "Category #2", "Id": "21"},
    {"cat": "Category #1", "Id": "11"},
    {"cat": "Category #1", "Id": "18"}
]

Вот почему я пытался упорядочить по indexOf (категория) в моем примере выше

Ответы [ 2 ]

2 голосов
/ 27 декабря 2011

Кажется, вы просто ищете нормальную стабильную сортировку?Собственная сортировка JS стабильна в большинстве браузеров (в каждом современном браузере последние два года или около того), поэтому просто:

items.sort( function( a, b ){
    return a.Id - b.Id;
} );

обычно будет работать, но она не стабильна в all браузеры, чтобы сделать это, сделайте что-то вроде:

for( var i=0... ){
   items[i].index = i;
}
items.sort( function( a, b ){
    return ( a.Id != b.Id ) ? ( a.Id - b.Id ) : ( a.index - b.index );
}

, который сортирует по Id, а затем в исходном порядке.

1 голос
/ 27 декабря 2011

Вы на правильном пути, ваша функция sort не должна быть сложной:

function group(array) {
    var i, categories = {};
    /* Build a map of categories and minimum indices: */
    for (i = 0; i < resultsArray.length; i++) {
        if (!categories[resultsArray[i].cat]) {
            categories[resultsArray[i].cat] = i;
        }
    }

    /* Sort the array using the minimum index: */
    return resultsArray.sort(function(one, other) {
        return categories[one.cat] - categories[other.cat];
    });
}

Пример: http://jsfiddle.net/dn2U5/

Это должно начать вас.К сожалению, функция проходит через массив дважды (что, очевидно, не оптимально).

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