2013-10-10 3 views
1

У меня есть данные, какJavaScript магистральная коллекция сортировать по нескольким полям

------------------------- 
id | name | parentId 
------------------------- 
1 | a | 
2 | z | 
3 | b | 
4 | z1 | 2 
5 | y2 | 1 
6 | y1 | 1 
7 | y3 | 1 
------------------------- 

в коллекции позвоночника.

Я хочу, чтобы сортировать по имени поля, но дочерний объект должен быть помещен чуть ниже родителя (на основе ParentID), т.е.

------------------------- 
id | name | parentId 
------------------------- 
1 | a | 
6 | y1 | 1 
5 | y2 | 1 
7 | y3 | 1 
3 | b | 
2 | z | 
4 | z1 | 2 
------------------------- 

Здесь y1, y2 и y3 вверх, потому что они являются дочерними элементами (id 1).

Я использую каркас сборщика компаратор. (Но компаратор только в javasript будет делать это - я буду конвертировать в базовый компаратор).

ответ

5
var comparator = function(a, b) { 
    var aName = a.get('name'), 
     bName = b.get('name'), 
     aParentId = a.get('parentId'), 
     bParentId = b.get('parentId'); 

    if(!aParentId || !bParentId || aParentId == bParentId) { 
     // In these 3 cases, name has precedence 

     if(aName < bName) { 
      return -1; 
     } 
     else if(aName > bName) { 
      return 1; 
     } 
     else { 
      return 0; 
     } 

    } else if(aParentId < bParentId) { 
     return -1; 
    } else /* aParentId > bParentId */ { 
     return 1; 
    } 
}; 

EDIT: Исправлено. Необходимо учитывать два уровня сортировки, имея в виду, что любой недостающий parentId равен равным parentIds.

Вы также можете реализовать его как список полей/адаптированных компараторов, которые выполняются один за другим, где следующий компаратор делегируется, когда текущий находит равенство.

var loopedComparator = function(a, b) { 
    var fields = [ 
    { 
     name: 'parentId', 
     comparator: function(a, b) { 
     return (!a || !b || a == b) ? 0 : (a < b) ? -1 : 1; 
     } 
    }, 
    { 
     name: 'name', 
     comparator: function(a, b) { 
     return (a == b) ? 0 : (a < b) ? -1 : 1; 
     } 
    } 
    ]; 

    var i, result = 0; 
    for(i in fields) { 
    var field = fields[i]; 
    result = field.comparator(a.get(field.name), b.get(field.name)); 
    if(result !== 0) { 
     return result; // On inequality we return right away 
    } 
    // Else we continue, delegating the comparison to the next field/comparator 
    } 

    // When the loop is done, or if fields was defined empty, we return the last equality 
    return result; 

}; 

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

+0

Да, этот компаратор сортируется по имени, но я хочу также сортировать по родительскому идентификатору (несколько столбцов). Пожалуйста, см. Мой отредактированный вопрос, который очистит вопрос. – Akshay

+0

Прошу прощения, я неправильно понял ваш вопрос. – thibauts

+0

@Akshay Исправлено. Я попытался уточнить предыдущий ответ. Надеюсь, это поможет вам. – thibauts

Смежные вопросы