Алгоритм сортировки массива по нескольким ключам

При работе с массивами данных, одна из наиболее частых задач — сортировка. Стандартную сортировку по одному ключу при помощи метода «.sort» я рассматривать не буду — там все просто и тривиально. Я хочу привести пример, как делать сортировку массива по нескольким ключам — например нам нужно отрендерить табличку, где люди будут отсортированы по возрасту, а внутри одной возрастной группы фамилии должны идти по алфавиту.

 

var arr = [
	{
		name: "Andy",
		surname: "Orlov",
		age: 14
	},
	{
		name: "Andy",
		surname: "Ivanov",
		age: 15
	},
	{
		name: "Bob",
		surname: "Akopyan",
		age: 25
	},
	{
		name: "Han",
		surname: "Solo",
		age: 65
	}
	
];

arr.sort(function(a, b) {	
	// ascending\descending will be changed if you replace "<" to ">"
	return  (b.name.toLowerCase() < a.name.toLowerCase()) - (a.name.toLowerCase() < b.name.toLowerCase()) || 		// sort by name
		(b.surname.toLowerCase() < a.surname.toLowerCase()) - (a.surname.toLowerCase() < b.surname.toLowerCase()) ||    // sort by surname
		(b.age.toLowerCase() < a.age.toLowerCase()) - (a.age.toLowerCase() < b.age.toLowerCase());			// sort by age
});

console.log(arr);

Как видите, ничего сложного, количество ключей может быть бесконечным. Единственное, не забывайте применять метод toLowerCase(), иначе сортировка будет работать некорректно. Чтобы поменять порядок сортировки на обратный - просто поменяйте знак "<" на ">" и наоборот.

Алгоритм лемматизации на javascript

Иногда возникает проблема при склонении слов в русском языке. Например, нам нужно в какой-нибудь CRM отобразить количество задач у пользователя. Вот так выглядит не очень: «Всего: 1 задач», «Всего: 5 задач», «Всего: 4 задач».  Звучит, мягко говоря не по-русски и режет слух и глаз. Без склонения на Javascript бывает сложно обойтись.

Проблема новичкам покажется очень сложной, но,  у склонения слов есть некоторая закономерность. Посмотрите сами: «1 задача, 2 задачи, 5 задач, 11 задач, 19 задач, 21 задача, 22 задачи, 25 задач и так далее». Видите закономерность? 1, 21, 31, 41 — всегда будет «задача». Если младший разряд больше 1-го и меньше 5, при этом само число при делении на 100 имеет остаток больше 20 (то есть, например, не число 12 и не 112), то будут «задачи». В остальных случаях «задач».

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

//Сама функция
function lemma( num, suffix ) {

	var keys = [2, 0, 1, 1, 1, 2],
	    mmod = num % 100,
	    suffixKey = ( mmod > 7 && mmod < 20 ) ? 2: keys[(mmod % 10 < 5 ? mmod % 10 : 5)];

	return suffix[suffixKey];
}

//Проверяем функцию на числах от 0 до 100
for(var i = 0, suff = ["задача", "задачи", "задач"]; i < 100 ; i++) {
	console.log("Всего: " + i + " " + lemma(i, suff));
}