Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   javascript сортировка option и value по алфавиту (https://javascript.ru/forum/dom-window/74169-javascript-sortirovka-option-i-value-po-alfavitu.html)

mopsusha 19.06.2018 17:00

javascript сортировка option и value по алфавиту
 
На странице есть списки например

Код:

<select multiple="multiple">
        <option value="2" selected="selected">С отделкой</option>
        <option value="3">Без отделки</option>
</select>

<select multiple="multiple">
        <option value="2" selected="selected">Банан</option>
        <option value="3">Абрикос</option>
<option value="4">Зелень</option>
</select>


Как выстроить эти списки по алфавиту(с сохранением value и selected у option) при загрузке страницы, чтобы получалось так

Код:

<select multiple="multiple">
        <option value="3">Без отделки</option>
        <option value="2" selected="selected">С отделкой</option>
</select>

<select multiple="multiple">
    <option value="3">Абрикос</option>
        <option value="2" selected="selected">Банан</option>
        <option value="4">Зелень</option>
</select>


j0hnik 19.06.2018 17:15

<select multiple="multiple">
		<option value="2" selected="selected">С отделкой</option>
		<option value="3">Без отделки</option>
	</select>

	<select multiple="multiple">
		<option value="2" selected="selected">Банан</option>
		<option value="3">Абрикос</option>
		<option value="4">Зелень</option>
	</select>

	<script>
		document.querySelectorAll('select').forEach(sel=>{
			[...sel.children].sort((a,b)=> a.text > b.text ? 1 : a.text < b.text ? -1 : 0).forEach(el=>sel.appendChild(el));
		});
	</script>

рони 19.06.2018 17:23

mopsusha,
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>

  <script>
document.addEventListener("DOMContentLoaded", function() {
    var select = document.querySelectorAll("select");
    [].forEach.call(select, function(sel) {
        [].slice.call(sel.options, 0).sort(function(a, b) {
            return a.text > b.text ? 1 : a.text < b.text ? -1 : 0
        }).forEach(function(o) {
            sel.appendChild(o)
        })
    })
});
</script>
</head>

<body>
<select multiple="multiple">
	<option value="2" selected="selected">С отделкой</option>
	<option value="3">Без отделки</option>
</select>

<select multiple="multiple">
	<option value="2" selected="selected">Банан</option>
	<option value="3">Абрикос</option>
<option value="4">Зелень</option>
</select>
</body>
</html>

рони 19.06.2018 17:25

j0hnik,
sort без return -1, не айс

j0hnik 19.06.2018 17:29

рони,
Какие нюансы?

рони 19.06.2018 17:31

Цитата:

Сообщение от j0hnik
Какие нюансы?

отсутствие сортировки, особенно в браузерах типа хром

j0hnik 19.06.2018 17:32

рони,
можете примерчик такого поведения черкануть?

рони 19.06.2018 17:35

j0hnik,
документации по sort, разве недостаточно?

j0hnik 19.06.2018 17:37

рони,
если не сложно уделите минутку... ;)

рони 19.06.2018 17:50

j0hnik,
<script>
var str = "12345678901234567890";
for (var i = 0; i < 50; i++) {
document.write("<br>"+str.split("").sort(function() {
   return Math.random() > 0.5
}).sort(function(a,b) {
   return a > b
})) //ожидаемый результат 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9

}

  </script>

j0hnik 19.06.2018 18:29

рони,
спасибо, вник в суть, к массивам больше 10 ячеек v8 применяет какую-то оптимизацию.

рони 19.06.2018 18:35

j0hnik,
да, да наплевать на документацию, это Google Chrome и Internet Explorer плохие, раз придерживаются правил )))

j0hnik 19.06.2018 18:46

рони,
IE придерживается и даж поддержка новых стандартов появляется спустя 3-4 года, а так да, хороший арбуз!

рони 19.06.2018 18:51

j0hnik,
c return -1 работает везде
<script>
var str = "12345678901234567890";
for (var i = 0; i < 50; i++) {
document.write("<br>"+str.split("").sort(function() {
   return Math.random() > 0.5
}).sort(function(a,b) {
   return a > b ? 1 : a < b ? -1 : 0
})) //ожидаемый результат 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9

}

  </script>

j0hnik 19.06.2018 18:52

рони, да знаю

рони 19.06.2018 18:54

:write: :) или так
<script>
var str = "12345678901234567890";
for (var i = 0; i < 50; i++) {
document.write("<br>"+str.split("").sort(function() {
   return Math.random() > 0.5
}).sort(function(a,b) {
   return a > b || -(a < b)
})) //ожидаемый результат 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9

}

  </script>

Manyasha 19.06.2018 19:16

рони,
а почему бы не так тогда (7-я строка)?))
return a > b || -1

рони 19.06.2018 19:17

:lol: или так

<script>
var str = "12345678901234567890";
for (var i = 0; i < 50; i++) {
document.write("<br>"+str.split("").sort(function() {
   return Math.random() > 0.5
}).sort(function(a,b) {
   return a.localeCompare(b,"ru")
})) //ожидаемый результат 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9

}

  </script>

рони 19.06.2018 19:18

Цитата:

Сообщение от Manyasha
return a > b || -1

как вернуть ноль?

Manyasha 19.06.2018 19:19

а зачем? Поменяются местами 5 и 5, это же не ошибка

j0hnik 19.06.2018 19:20

Цитата:

Сообщение от рони
или так

Это уже слишком

j0hnik 19.06.2018 19:22

Цитата:

Сообщение от Manyasha
а зачем? Поменяются местами 5 и 5, это же не ошибка

лишняя операция

Manyasha 19.06.2018 19:26

Ну тогда так)):
return a - b;

рони 19.06.2018 19:38

Цитата:

Сообщение от Manyasha
Ну тогда так)):

сортируются в примере строки!!! а не числа

рони 19.06.2018 19:39

Manyasha,
Array/sort

рони 19.06.2018 19:46

Manyasha,
<script>
var stringArray = ['Банан', 'Абрикос', 'Зелень'];
stringArray.sort(function(a,b) {
  return a - b
})
document.write(stringArray + " false <br>")
stringArray.sort() //по умолчанию сортировка строк a > b ? 1 : a < b ? -1 : 0
document.write(stringArray + " true")

</script>

Alexandroppolus 19.06.2018 20:16

Цитата:

Сообщение от j0hnik (Сообщение 487744)
рони,
спасибо, вник в суть, к массивам больше 10 ячеек v8 применяет какую-то оптимизацию.

эта "оптимизация" называется быстрая сортировка )
маленькие массивы сортируются каким-то другим методом, который быстрее если мало элементов.

j0hnik 19.06.2018 20:27

Alexandroppolus,
наоборот, для маленьких оптимизации нет, для больших есть. помните эту кату с самописным реверсом??

Alexandroppolus 19.06.2018 20:40

j0hnik,
помню, только она тут не при чем.

на больших массивах быстрая сортировка уделывает все остальные, потому что она асимптотически выгоднее. На маленьких асимптотика работает слегка по другому (разница между n*n и n*ln(n) копеечная, в итоге начинают рулить коэффициенты), и какой-нибудь "пузырёк" может оказаться быстрее.

а так - оптимизация есть в обоих случаях. Ну и что, что массив маленький. А если надо отсортировать миллион таких маленьких? потому всё ускорено по максимуму

j0hnik 19.06.2018 21:09

https://jsperf.com/45435435tret больший по размерам массив сортируется быстрей. в хроме
console.log([0,1,2,3,4,5,6,7,8,9].sort((a,b)=>b)); //логичное поведение

console.log([0,1,2,3,4,5,6,7,8,9,1].sort((a,b)=>b)); //не логичное

j0hnik 19.06.2018 21:15

Alexandroppolus,
может и есть но, с маленьким вроде все логично выводит, а там пытается "хитрить"

laimas 19.06.2018 21:20

Цитата:

Сообщение от рони
/по умолчанию сортировка строк a > b ? 1 : a < b ? -1 : 0

var a = ['11-05-2018', '12-05-2017', '10-04-2017'];
a.sort();

alert(a);
alert('12-05-2017' > '11-05-2018')


Опасно так все строки сортировать ;)

рони 19.06.2018 21:30

laimas,
ты сортируешь строки, а результат хочешь как от даты, в строках "8" больше чем "20"

laimas 19.06.2018 21:44

Цитата:

Сообщение от рони
ты сортируешь строки, а результат хочешь как от даты

А какая разница, дата ведь это строковое значение, именно поэтому не стоит оперировать форматом даты отличном от европейского - YYYY-MM-DD. Но ведь не запрещено. :)

Такие же проблемы могут быть и просто с числами (уберите дефисы, результат не лучше будет, так как это строки). А есть еще понятие "натуральная сортировка", в JS готовой функции для нее тоже нет.

рони 19.06.2018 21:52

laimas,
не осилил

laimas 19.06.2018 22:03

Цитата:

Сообщение от рони
не осилил

Что именно? Хотя согласен, не совсем корректно написал. :)

Ну например есть массив имен файлов, которые надо отсортировать:

var a = ["img12.png", "img10.png", "img2.png", "img1.png"];
a.sort();

alert(a);


и получим не то чего бы хотелось - img1.png, img2.png, img10.png, img12.png. Проблема в том, что сравнение a > b будет косячит с числами.

рони 19.06.2018 22:05

laimas,
спасибо, но я пас.

рони 19.06.2018 22:12

Цитата:

Сообщение от laimas
Ну например есть массив имен файлов, которые надо отсортировать:

возможно я что-то не понимаю ...
var a = ["img12.png", "img10.png", "img2.png", "img1.png"];
a.sort(function(a,b) {
  return a.match(/\d+/)[0]  - b.match(/\d+/)[0]
});

alert(a);

laimas 19.06.2018 22:18

Цитата:

Сообщение от рони
возможно я что-то не понимаю ...

Все вы понимаете. ) Данный код вернет нужное, но только конкретно к данному случаю. Собственно вся эта тема и рассматривала "идеальный случай". :)

Проверьте свой код с таким, например, массивом: ["iag12.png", "iq10.png", "img2.png", "img1.png"] - с цифрами все будет Ок, но ведь не верно же будет. )

рони 19.06.2018 22:26

Цитата:

Сообщение от laimas
Проверьте свой код с таким,

а зачем? с новым набором будет иной код ... какое будет тз, такая и будет сортировка, ...


Часовой пояс GMT +3, время: 18:08.