Сортировка таблицы js.


Сортировка - это расположение строк в таблице в определенном порядке. Чаще всего необходимо сортировать строки по данным одного или нескольких столбцов.

Сортировку можно производить как по возрастанию, так и по убыванию.

При сортировке по возрастанию используется следующий порядок. Сначала числа от наименьшего отрицательного до наибольшего положительного числа, затем различные знаки (+, -, !, и др.), затем английские буквы, затем русские буквы. При сортировке по убыванию порядок заменяется на обратный.

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

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

Сортировку таблицы можно выполнять при работе во вкладке Главная или Макет .

Сортировка таблицы производится следующим образом:

Установите курсор в любую ячейку таблицы.

Нажмите кнопку Сортировка в группе Абзац вкладки Главная или в группе Данные вкладки Макет .

В окне Сортировка в открывающемся списке поля Сначала по выберите столбец, по данным которого будет выполняться сортировка таблицы. В списке поля Т ип можно выбрать тип данных, по которым сортируется таблица, но обычно Word это делает автоматически. Установите переключатель направления сортировки по возрастанию или по убыванию.

В окне Параметры сортировки установите флажок только столбцы

8.4. Вычисления в таблице

В таблицах Word можно выполнять несложные вычисления с использованием формул. Для этого:

Установите курсор в ячейку, в которой требуется получить результат вычисления.

Во вкладке Макет в группе Данные нажмите кнопку Формула . Если эта кнопка не отображается, щелкните по стрелке кнопки Данные и, после отображения кнопки, нажмите ее.

В окне Формула (рис. 8.6) в поле Формула введите формулу. Для выбора функции можно воспользоваться списком поля Вставить функцию . При желании в списке поля Формат числа можно выбрать числовой результат вычисления (числовой с разделителем разрядов, денежный, процентный).

Рис. 8.6. Создание формулы в ячейке

В некоторых случаях формула в окне Формула может быть записана автоматически. Например, если ячейка находится ниже ячеек с числами, будет записана формула = SUM (ABOVE) , что означает суммирование всех вышерасположенных ячеек. Если ячейка находится правее ячеек с числами, будет записана формула = SUM (LEFT) , что означает суммирование всех слева расположенных ячеек. Если требуется именно такое действие, можно применить эти формулы. В противном случае поле следует очистить и ввести формулу самостоятельно.

Формула вставляется в ячейку таблицы как специальное поле. При изменении значений в вычисляемых ячейках результат не будет автоматически изменяться. Для пересчета следует выделить ячейку и нажать клавишу F9.

8.5. Размещение таблицы в документе

Установка режима обтекания текстом.

Вставленная в документ таблица по умолчанию размещается без обтекания текстом с выравниванием по левому полю страницы.

Для выравнивания таблицы по краям страницы достаточно ее выделить и воспользоваться кнопками группы Абзац вкладки Главная . При таком выравнивании таблицы режим обтекания текстом не изменяется.

Изменить режим обтекания и положение таблицы можно следующим образом:

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

Нажмите на левую кнопку мыши и перетащите маркер. В процессе перетаскивания граница таблицы будет отображаться пунктиром.

Можно точно настроить положение таблицы на странице документа. Для этого:

Установите курсор в любой ячейке таблицы.

Во вкладке Макет в группе Таблица нажмите кнопку Свойства .

Во вкладке Таблица окна Свойства таблицы в разделе Обтекание выберите режим В округ и нажмите кнопку Размещение .

В окне Размещение таблицы (рис. 8.7) в разделе По горизонтали в раскрывающемся списке относительно можно выбрать, относительно какого элемента страницы будет выравниваться таблица: колонки, поля или страницы, а в списке поля Положение можно выбрать расположение таблицы (Слева , Справа , От центра , Внутри , Снаружи ) или ввести с клавиатуры требуемое значение в сантиметрах. Аналогично можно указать размещение таблицы и по вертикали.

Рис. 8.7. Установка положения таблицы

Для отказа от режима обтекания таблицы текстом следует установить курсор в любой ячейке таблицы, во вкладке Макет в группе Таблица нажать кнопку Свойства , во вкладке Таблица окна Свойства таблицы в разделе Обтекание выбрать режим нет .

Перенос заголовков таблицы на следующую страницу.

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

Установите курсор в первую строку таблицы или, если в качестве заголовков используется несколько первых строк, выделите их.

Во вкладке Макет в группе Данные нажмите кнопку Повторить строки заголовков .

Преобразование таблицы в текст.

Всю таблицу или ее фрагмент можно преобразовать в текст. Для этого:

Установите курсор в любую ячейку таблицы или выделите преобразуемый диапазон

Во вкладке Макет в группе Данные нажмите кнопку Преобразовать в текст .

В окне Преобразование в текст укажите символ, который будет разделять фрагменты текста, сформированные из отдельных ячеек таблицы. Это может быть один из типовых символов (знак абзаца, знак табуляции или точка с запятой) или любой символ по вашему усмотрению, например, точка, пробел, запятая и т. п. В этом случае установите переключатель другой, поставьте курсор в рядом расположенное поле и с клавиатуры введите символ разделителя. Если таблица содержит вложенные таблицы, их также можно преобразовать в текст (флажок вложенные таблицы).

Рис. 11.20. Преобразование таблицы в текст

Выбранный разделитель разделяет данные ячеек одной строки; независимо от выбранного разделителя разделителем строк таблицы является знак абзаца.

Встала задача отсортировать таблицу на яваскрипте по любому столбику. Известный всем плагин tablesorter у меня не заработал, и я решил, что быстрее и удобнее будет написать свой скрипт. Вот, что получилось через час:

Скрипт получился из 20 строк, 1 кб (готовый tablesorter весит 13 кб и дольше «усваивается»). Ещё одно отличие: подготовительные операции для сортировки происходят по клику; это имеет смысл, потому что сортировка нужна не всем.

Первым делом нужно присвоить идентификаторы каждой строчке таблицы. Это лучше сделать сразу на сервере при выводе таблицы:



...

Теперь идентификатор будет привязан к строке с данными, и если её переставить в другое место, ничего не перепутается.

Сортировка массива

В интернете можно найти решения, где таблица целиком переводится в многомерный массив, а затем этот массив сортируется, после чего формируется и выводится новая таблица на место старой. Однако мне этот способ показался слишком громоздким, ведь достаточно держать в памяти всего два столбика:
1) по которому происходит сортировка,
2) столбик идентификаторов.

Можно обойтись простым массивом (ключ => значение), где ключ отвечает за номер строки. Но лично мне проще использовать двумерный массив, чтобы не запутаться между ключами и значениями.

На примере моей таблицы:

А первые значения массива указывают, в каком порядке будут идти строки отсортированной таблицы.

Кстати, данный метод аналогичен сортировке в MySQL с использованием вре́менных таблиц.

Во временный массив желательно класть подготовленные значения, которые быстро и легко сравнивать. Лишнее (тэги и css) надо отбросить, отформатированные числа перевести в обычные числа (20 000 → 20000), а строки можно превратить в некие эквиваленты. Например, в моём случае единственный текстовый столбик содержит только два слова: свободен и бронь . У них разная длина, а значит, во временный массив можно записать только длину слов — этого хватит для корректного сравнения.

var z=$(this).children("td").eq(i_s).html().split(" ").join(""); //убираем пробелы
if(isFinite(z)) {z=parseInt(z);} else {z=z.length;} //число остаётся числом, а у строк оставляем только длину

В яваскрипте есть готовый алгоритм сортировки, использующий функцию сравнения двух элементов:

function sName(a,b) { //задаём функцию сравнения
if(a < b) {return (-1)*s_vozr;}
else if(a > b) {return s_vozr;}
else {return 0;}
}

multi.sort(sName); //сортируем массив multi, указав функцию sName

Функция sName(a,b) возвращает −1, 0 или 1. Если умножить возвращаемое значение на −1, то это изменит направление сортировки (по возрастанию или по убыванию). Таким образом, при помощи параметра s_vozr можно управлять направлением сортировки (если повторно кликнули по столбцу, параметр s_vozr меняет знак).

Перестановка строк таблицы

Теперь надо как-то удалить старую таблицу и показать новую, отсортированную. Тесты я не проводил (буду благодарен за ссылки в комментариях), но почти уверен, что экономичнее перемещать небольшие кусочки данных (то есть строки), чем парсить заново всю таблицу. Если это и не оптимизировано сейчас, то в будущем перемещение элементов должно занимать меньше времени, чем удаление старых и обработка новых элементов; а в нашем случае речь идёт о вставке довольно большой таблицы.

Как переделать старую таблицу в новую, используя перемещение строк? Пройдёмся в цикле по нашему вре́менному массиву, перемещая нужные строчки таблицы в её конец.

От того, куда перемещать строки — в конец или в начало — очевидно, зависит получаемое направление сортировки. Но эффективнее их сдвигать именно в конец. А если нужно изменить направление сортировки, то лучше пройтись по массиву в обратную сторону (или изначально сформировать обратный массив).

Достаточно часто пользователям интернет приходится сталкиваться с большим объемом информации, представленным в виде таблицы. Не менее часто требуется получить результаты в ином порядке, чем они представлены первоначально. Большинство web-мастеров решает эту проблему применением сортировки на сервере, для чего используется перезагрузка страницы. Действительно, серверные языки предоставляют гораздо больше возможностей отсортировать многомерный массив по определенному значению, чем скриптовые языки, выполняющиеся непосредственно на стороне клиента. Решение сортировать данные на стороне сервера вполне оправданно с точки зрения трудозатрат программиста, так как многие серверные языки имеют встроенные функции сортировки многомерных массивов, и поэтому не требуется вдумываться в алгоритмы сортировки, что-то изобретать или перестраивать алгоритм под свои нужды. Но все-таки такое решение не оправдано, если подходить к этой проблеме с точки зрения пользователя. Вначале посетителю сайта требуется дождаться достаточно длительной загрузки страницы, просмотреть результаты, нажать на кнопку "Отсортировать" и... опять дожидаться, пока сервер закончит работу и вернет результат. Такие множественные перезагрузки страницы никак не способствуют популярности сайта у посетителя. В конце-концов, устав дожидаться очередной загрузки страницы, или испугавшись лишнего траффика, он покинет сайт в поисках более лояльного к нему web-мастера. Решением данной проблемы, а именно эффективной сортировки данных и формирования результирующей таблицы, я и предлагаю заняться в этой статье. А в качестве примера данных будет выступать информация о книгах: дата написания, название книги и ее автор.

Начнем с функции fillArray, которая и будет эмулировать многомерный массив, а вернее создать класс-объект с членами - данными многомерного массива. Приведем ее код:

Листинг 1: 1 function fillArray(years, books, authors) { 2 authors = upCs(authors, " "); 3 authors = upCs(authors, "-"); 4 books = upCs(books, ""); 5 6 this.years = years; 7 this.yweight = weight(years); 8 this.books = books; 9 this.bweight = weight(books); 10 this.authors = authors; 11 this.aweight = weight(authors); 12 }

Разберем данные по строкам. Во второй строке вызывается функция upCs с параметром authors и пробелом в качестве второго параметра. Функция upCs создает заглавные буквы в начале строки и перед каждым вхождением второго аргумента. Эта функция была написана исключительно потому, что не все обрабатывают данные должным образом и вполне могут написать имя писателя, например, с маленькой буквы. Применение такой функции устраняет возможную ошибку программиста в заполнении массива данными, а также позволяет быть уверенным, что в функции сортировки не будет неверного сравнения заглавных букв со строчными. Впрочем, если вы уверены в том, что данные будут занесены верно, можете убрать вызовы этой функции:

Листинг 2: 1 function upCs(str, param) { 2 var tmpStr = str.substring(0, 1).toUpperCase() + str.substring(1); 3 if(!param) 4 return tmpStr; 5 var separator = tmpStr.indexOf(param); 6 var retStr = tmpStr; 7 if(separator != -1) 8 retStr = tmpStr.substring(0, separator); 9 10 while(separator != -1) { 11 tmpStr = tmpStr.substr(separator + 1, 1).toUpperCase() + tmpStr.substring(separator + 2); 12 separator = tmpStr.indexOf(param); 13 if(separator != -1) 14 retStr += param + tmpStr.substring(0, separator); 15 else 16 retStr += param + tmpStr; 17 } 18 19 return retStr; 20 }

Эта же функция, вызванная с пустым вторым аргументом, возвращает результат с заглавной буквой только в начале строки. Теперь обратимся к строке 7, листинга 1. Здесь вызывается функция weight, которая возвращает числовые значения каждого символа аргумента в виде массива. Для чего я ее написал? Дело в том, что коды символов русского алфавита в браузере идут последовательно, кроме кода символа буквы "ё". Код этого символа больше кодов символов остального алфавита, поэтому приходится присваивать такое "весовое" значение этому символу, которое соответствовало бы его позиции в алфавите. Вот код этой функции:

Листинг 3: 1 function weight(str) { 2 var retArray = new Array(); 3 4 for(var i = 0; i < str.length; i++) { 5 var tmp = str.charCodeAt(i); 6 if(tmp >= 1046 && tmp < 1078) 7 tmp++; 8 else if(tmp == 1025) 9 tmp = 1046; 10 else if(tmp >= 1078) 11 tmp++; 12 else if(tmp == 1105) 13 tmp = 1078; 14 retArray[ i ] = tmp; 15 } 16 17 return retArray; 18 }

Ну что же, функции, необходимые для создания нашего многомерного массива готовы. Осталось создать массив и заполнить его данными:

Листинг 4: 1 var txt = ; 2 txt[ 0 ] = new fillArray("1959", "фрейд", "сартр жан-поль"); 3 txt[ 1 ] = new fillArray("1940", "подростки", "сэлинджер джером"); 4 txt[ 2 ] = new fillArray("1946", "пена дней", "виан борис"); 5 txt[ 3 ] = new fillArray("1948", "осадное положение", "камю альбер"); 6 txt[ 4 ] = new fillArray("1899", "об иноческой жизни", "рильке райнер мария"); 7 txt[ 5 ] = new fillArray("1849", "аннабель Ли", "по эдгар"); 8 txt[ 6 ] = new fillArray("1917", "дагон", "лавкрафт говард"); 9 txt[ 7 ] = new fillArray("1915", "процесс", "кафка франц"); 10 txt[ 8 ] = new fillArray("1989", "египет Рамсесов", "монтэ пьер"); 11 txt[ 9 ] = new fillArray("1932", "мастер и Маргарита", "булгаков михаил");

Обратить внимание стоит лишь на то, что года, когда были написаны книги, я передаю в функцию в качестве строкового параметра, а не числового. Делается это для того, чтобы не писать несколько функций сортировки.

Насколько быстр такой метод заполнения массива? На компьютере со средней производительностью загрузка 1000 элементов происходит за 450 - 800 миллисекунд. Но поскольку пользователь будет получать массив такого размера не сразу, а по частям, и размер этих частей будет сильно зависеть от скорости его соединения с интернет, то время, затрачиваемое на создание элемента массива и определение весовых значений его данных, будет незаметно пользователю.

Я подошел к самой интересной части данной статьи, а именно - к непосредственной работе с данными. В качестве функции сортировки данных я выбрал сортировку Хоара, которая, как мне кажется, наиболее соответствует поставленной задаче в начале статьи. Вот ее код, нюансы которого рассмотрю несколько более подробно.

Листинг 5: 1 function quickSort(l, h, type) { 2 var low = l; 3 var high = h; 4 var rt = eval("txt[ " + Math.round((l + h) / 2) + " ]"); 5 var middle = new fillArray(rt.years, rt.books, rt.authors); 6 7 do { 8 9 while(isLow(eval("txt[ " + low + " ]"), middle, type)) 10 low++; 11 12 while(isLow(middle, eval("txt[ " + high + " ]"), type)) 13 high--; 14 15 if(low = 1046 && tmp < 1078) tmp++; else if(tmp == 1025) tmp = 1046; else if(tmp >= 1078) tmp++; else if(tmp == 1105) tmp = 1078; retArray[ i ] = tmp; } return retArray; } function fillArray(years, books, authors) { authors = upCs(authors, " "); authors = upCs(authors, "-"); books = upCs(books, ""); this.years = years; this.yweight = weight(years); this.books = books; this.bweight = weight(books); this.authors = authors; this.aweight = weight(authors); } function isLow(low, high, type) { var len1 = low[ type ].length; var len2 = high[ type ].length; var length = len1 < len2 ? len1: len2; for(var i = 0; i < length; i++) { var str1 = low[ type ][ i ]; var str2 = high[ type ][ i ]; if(str1 < str2) return true; if(str1 > str2) return false; } if(len1 < len2) return true; return false; } function quickSort(l, h, type) { var low = l; var high = h; var rt = eval("txt[ " + Math.round((l + h) / 2) + " ]"); var middle = new fillArray(rt.years, rt.books, rt.authors); do { while(isLow(eval("txt[ " + low + " ]"), middle, type)) low++; while(isLow(middle, eval("txt[ " + high + " ]"), type)) high--; if(low







2024 © gtavrl.ru.