Как отсортировать массив с добавлением разделителей групп?

Хочу задать вопрос, из-за которого появляются темы "Сколько будет таких вопросов", но задам.
Делаю скрипт, выводящий на экран список в алфавитном порядке и хочу, чтобы список выводился в следующем порядке:
Буква
Слова по алфавиту, начинающихся с этой буквы, т.е.
A
Adam
J
John
M
Mary
Mike
$scope.dis =
          [{name:'John', anchor:'123'},
           {name:'Mary' , anchor:'123'},
           {name:'Mike'  anchor:'123'},
           {name:'Adam' anchor:'123'},"

Какая последовательность действий должна быть у скрипта?
1) Отсортировать массив по алфавиту $scope.names = $scope.dis.sort();
Брать по элементу, куда то записывать первый символ каждого элемента names, а потом сравнивать со следующей буквой?
Вообще какой способ есть менее затратный?
Это ни в коем случае не задание - хочется именно алгоритм
  • Вопрос задан
  • 729 просмотров
Решения вопроса 1
qfox
@qfox
Ответы есть у меня
Толи я не понимаю, толи это ответ:
// сортируем
var sorted = $scope.dis.sort(function (a, b) {
  return a.name > b.name? 1 :  -1;
});
// собираем сам массив
var sortedWithGroups = sorted.reduce(function (res, a) {
  // добавляем дополнительно букву перед первым словом на новую букву
  // если это первое слово на эту букву
  if (res.lastGroup !== a.name[0]) {
    res.lastGroup = a.name[0];
    res.push({name: a.name[0], group: true});
  }
  // добавляем саму ссылку
  res.push(a);
  return res;
}, []);

В итоге в sortedWithGroups отсортированный массив с группировкой по буквам.

p.s. Разделил на переменные только ради комментариев. Все это можно собрать в несколько строк и вызывать reduce сразу после sort в одной конструкции.

Ссылки:
Array.prototype.sort: https://developer.mozilla.org/en-US/docs/Web/JavaS...
Array.prototype.reduce: https://developer.mozilla.org/en-US/docs/Web/JavaS...
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
standy
@standy
Алгоритм такой:
1. Отсортировать всё по алфавиту.
2. Выводить слова в цикле, при этом выводить букву-заголовок только если она не совпадает с первой буквой прошлого слова.
Ответ написан
Я использую lodash/underscore для таких зачач.

_.sortBy(['a', 'b', 'c'], function(s){ 
    return s.charCodeAt() * -1;
});


А вообще в angularjs есть нативный сервис $filter. Он тоже это умеет делать.

https://docs.angularjs.org/api/ng/filter/orderBy
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы