Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Сортировка элементов по количеству (https://javascript.ru/forum/misc/22123-sortirovka-ehlementov-po-kolichestvu.html)

Dorian_bs 07.10.2011 02:10

Сортировка элементов по количеству
 
Всем привет!
Стало необходимо написать скрипт для сортировки элементов (div) по количеству.

Например:

Есть список названий..

<div class="tops">Сахар</div>
<div class="tops">Сахар</div>
<div class="tops">Молоко</div>
<div class="tops">Огурцы</div>
<div class="tops">Молоко</div>
<div class="tops">Мед</div>
<div class="tops">Огурцы</div>
<div class="tops">Сахар</div>


Необходимо подсчитать количество одинаковых продуктов и отсортировать их по убыванию.

Получится:

Так как сахара 3 шт. - 1-ое место.
Так как молока 2 шт. - 2-ое место.
Так как огурцов 2 шт. - 3-е место.
Так как меда 1 шт. - 4-ое место.

Максимальное количество выводимых продуктов - 5;

<div class="tops">1. Сахар</div>
<div class="tops">2. Молоко</div>
<div class="tops">3. Огурцы</div>
<div class="tops">4. Мед</div>


Сколько уже на листочке алгоритмов не рисовал - не получается.
Помогите. :(

FINoM 07.10.2011 02:52

Покажите, как сопоставлены названия и количество.

Dorian_bs 07.10.2011 03:03

FINoM,
В каком смысле?

Вот написал скрипт... Только пока сортировки по кол. нету и ограничение на кол.

HTML:
<div style="display:none">
  <div class="tAuthor">Сахар</div>
  <div class="tAuthor">Сахар</div>
  <div class="tAuthor">Молоко</div>
  <div class="tAuthor">Сахар</div>
  <div class="tAuthor">Мед</div>
  <div class="tAuthor">Сахар</div>
  <div class="tAuthor">Молоко</div>
  <div class="tAuthor">Сахар</div>
  <div class="tAuthor">Молоко</div>
  <div class="tAuthor">Огурцы</div>
  <div class="tAuthor">Мед</div>
</div>

<div class="twoss" title="Тут создается новый список"></div>


JS:
$(function () {
    $('.tAuthor').each(function(i){
         var names = $(this).html();
         var usi = $('.tAuthor2:contains('+names+')').html();
         if(names!=usi) {
           var aa = $('.tAuthor:contains('+names+')').length;
           $('.twoss').append('<b class="tAuthor2">'+names+'</b>, '+aa+'<br>');
         }
    });
});


Помогите сортировку по убыванию, и макс кол.

Dorian_bs 07.10.2011 03:16

Лимит сделал
$(function () {
    $('.tAuthor').each(function(i){
         var names = $(this).html();
         var usi = $('.tAuthor2:contains('+names+')').html();
         var aa2 = $('.tAuthor2').length;
         if(names!=usi && aa2<5) {
           var aa = $('.tAuthor:contains('+names+')').length;
           $('.twoss').append('<b class="tAuthor2">'+names+'</b>, '+aa+'<br>');
         }
    });
});

Осталось сортировку..

Как я понимаю, сейчас необходимо добавлять элементы через append и prepend.
Если Больше макс. значения - prepend, а если меньше - append.

FINoM 07.10.2011 05:57

Цитата:

Сообщение от Dorian_bs
В каком смысле?

Извините, не врубился. Сейчас 5 утра, я вам не отвечу, тем более на код с переменными usi, aa, aa2 :D

ksa 07.10.2011 08:37

Цитата:

Сообщение от Dorian_bs
Сколько уже на листочке алгоритмов не рисовал - не получается.

Алгоритм стандартный:
- Делаешь массив типа
var a=[{Name: 'продукт', All: N}]

- вызываешь сортировку того массива
a.sort(function (a, b){b.All-a.All})

- Формируешь результирующий хтмл

Dorian_bs 07.10.2011 12:20

ksa,
Спасибо)
Не могли бы Вы привести пример использования в данном случае?

Вот изменил скрипт. Теперь все данные заносятся в массив.
Как их теперь отсортировать? И удалить повторяющиеся?
Читал про jQuery.unique, но не понял его применения..
А для сортировки, если прописать "array.sort(function (a, b){b.All-a.All})" - не работает.

$(function () {
 var array = [];
 $('.tAuthor').each(function(i){
    var Name = $(this).html();
    var NumRep = $('.tAuthor:contains('+Name+')').length;
    var hash = {'Name': Name,'All': NumRep}
    var rezArr = array.push(hash);
    array.sort(function (a, b){b.All-a.All});
 });
 console.log(array)
});

ksa 07.10.2011 13:40

Цитата:

Сообщение от Dorian_bs
Не могли бы Вы привести пример использования

Давот только недавно предлогалось несколько вариантов аналогичной сортировки. :D
В той теме много кто отписался своими вариантами... Ключевые коды я привёл... Остальное за оплату. :)

Dorian_bs 07.10.2011 13:49

Спасибо

aiky 07.10.2011 23:16

var arr = ['Сахар','Сахар','Молоко','Огурцы','Молоко','Мед','Огурцы','Сахар'];
arr.sort();

var cur = arr[0];
var k = 1;
var tmp = {
	'arr':[],
	'hash':{},
	'add':function(k,val){
		if(!tmp.hash[k]){
			tmp.hash[k] = [];
			tmp.arr.push(k);
		}
		tmp.hash[k].push(val);
	}
}

for(var i = 1; i < arr.length; i++){
	if(arr[i] !== cur){
		tmp.add(k,cur);
		cur = arr[i];
		k = 1;
	}
	else k++;
}
tmp.add(k,cur);
tmp.arr.sort(function(a,b){return b - a});

arr = [];
for(var i = 0; i < tmp.arr.length; i++)
  for(var j = 0; j < tmp.hash[tmp.arr[i]].length; j++) arr.push(tmp.hash[tmp.arr[i]][j]);

delete cur;
delete k;
delete tmp;

alert(arr);

Dorian_bs 08.10.2011 00:03

aiky,
Спасибо большое! Очень ВАМ БЛАГОДАРЕН! :thanks:

Sweet 08.10.2011 00:26

aiky, спешу огорчить вас, оператор delete не удаляет переменные, только свойства.

ksa 08.10.2011 09:05

Предложу такой вариант...

var a = ['Молоко','Огурцы','Молоко','Сахар','Сахар','Мед','Огурцы','Сахар'];
var i,b=[],c=[]
for (i=0; i<a.length; i++) {
	b[a[i]]=(b[a[i]] || 0)+1
}
for (i in b) {
	c[c.length]={
		Name: i,
		All: +b[i]
	}
}
c.sort(function (a,b){return b.All-a.All})
for (i=0; i<c.length; i++) {
	alert(c[i].Name+'='+c[i].All)
}

aiky 08.10.2011 10:46

Цитата:

Сообщение от Sweet
спешу огорчить вас, оператор delete не удаляет переменные, только свойства.

Да, виноват, варианта 2 - инициализирвать временные переменные без var, либо как элементы объекта tmp.

Kolyaj 08.10.2011 12:08

aiky,
как насчёт правильного варианта делать все переменные локальными?

рони 08.10.2011 12:30

Вариант ...
<script type="text/javascript">
var a = ['Молоко','Огурцы','Молоко','Сахар','Сахар','Мед','Огурцы','Сахар'],
    i, b = {},
    c = [];
for (i = 0; i < a.length; i++) a[i] in b ? b[a[i]]++ : (b[a[i]] = 1, c.push(a[i]));
c.sort(function (d, e) {
    return b[e] - b[d]
});
for (i = 0; i < c.length; i++) document.write(i + 1 + ". " + c[i] + "<br />");
</script>

stopkran 08.10.2011 15:06

Написал вариант, а потом увидел, что он почти совпадает с вариантом ksa. Ну, всё равно выложу (проструктурировал получше, да и вывод результатов удобнее):

var arr = ['Сахар','Сахар','Молоко','Огурцы','Молоко','Молоко','Молоко','Мед','Огурцы','Сахар'],
tmp_obj = {}, tmp_arr = [], i, l = arr.length;

//заполняем временный объект и подсчитываем количество
for (i = 0; i < l; i ++) tmp_obj[arr[i]] = (tmp_obj[arr[i]] || 0) + 1;

//превращаем временный объект в массив, чтоб сортировать
for (i in tmp_obj) tmp_arr.push([i, tmp_obj[i]])

tmp_arr.sort(function(a,b){return b[1] - a[1]});

alert(tmp_arr.join('; '))

Kolyaj 08.10.2011 16:11

Цитата:

Сообщение от stopkran
(проструктурировал получше

Писать всё в одну строчку называется получше проструктурировал?

stopkran 08.10.2011 17:32

Kolyaj,
вам действительно надо объяснить подробно, что именно я сделал? Или ваш вопрос - обычная вежливость, не требующая ответа?

aiky 08.10.2011 21:08

stopkran,
Во, все-таки кириллицу возможно в ключах использовать, не решился.
Так гораздо все проще.

stopkran 09.10.2011 08:57

aiky,
наверное, все тут сговорились вас огорчать :-), но всё-таки кириллицу в ключах лучше не использовать. У меня от этого были проблемы в Опере. Предположительно, этих проблем можно было бы избежать с помощью Юникод. Но наверняка я этого не знаю, поэтому решил проблему радикально - с помощью escape. В нашем случае можно делать примерно так:
var arr = ['Сахар','Сахар','Молоко','Огурцы','Молоко','Молоко','Молоко','Мед','Огурцы','Сахар'],
tmp = [], names = {}, out = '', l = arr.length, i = j = -1, k,

cmp = function(a, b) {return b[1] - a[1]},

add = function (name) {
	//список уникальных имён
	if (!(name in names)) names[name] = ++j
	k = tmp[names[name]]
	//пополняем массив сортировки (или количество в существующем элементе)
	tmp[names[name]] = [k && k[0] || unescape(name), (k && k[1] || 0) + 1]
};

while (++i < l) add(escape(arr[i]))
tmp.sort(cmp)
alert(tmp.join('; '))

aiky 09.10.2011 18:54

Цитата:

Сообщение от stopkran
но всё-таки кириллицу в ключах лучше не использовать

:-) хотел чтобы Вы это сами произнесли

escape ...сурово

Dorian_bs 10.10.2011 12:19

Спасибо огромное за помощь!)))


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