SELECT * ,
DATE_ADD(
birthday,
INTERVAL IF(DAYOFYEAR(birthday) >= DAYOFYEAR(CURDATE()),
YEAR(CURDATE())-YEAR(birthday),
YEAR(CURDATE())-YEAR(birthday)+1
) YEAR
) AS `next_birthday`
FROM `users`
WHERE
`birthday` IS NOT NULL
ORDER BY DATEDIFF(CURDATE(), `next_birthday`) DESC
Есть двумерный массив: массив с числовыми индексами, где каждый элемент - это ассоциативный массив. Например, массив пользователей:
$users = [
['id' => 1, 'name' => 'Bob', 'age' => 30],
['id' => 12, 'name' => 'Alice', 'age' => 20],
['id' => 34, 'name' => 'Trump', 'age' => 69]
];
Требуется отсортировать массив по полю name Простое и элегантное решение в одну строку (>= PHP 5.5)
array_multisort($users, array_column($users, 'name'));
Выбирает связанных template_field с сортировкой по весу групп template_field_group.weight
class AppTemplate extends \yii\db\ActiveRecord
{
public function getFields()
{
return $this->hasMany(TemplateField::className(), ['app_template_id' => 'id'])
->innerJoin("template_field_group", "template_field.template_field_group_id = template_field_group.id")
->orderBy(['template_field_group.weight' => SORT_DESC, 'template_field.template_field_group_id' => SORT_ASC]);
}
}
Иногда требуется, чтобы определённые ключи в массиве оказались в начале в определённом порядке.
$data = [
'orange' => 'orange',
'apple' => 'tasty',
'carpet' => 'old',
'car' => 'fast',
];
$result = orderByKeys($data, ['car', 'carpet']);
Получим:
$data = [
'car' => 'fast',
'carpet' => 'old',
'orange' => 'orange',
'apple' => 'tasty',
];
function orderByKeys(array $array, array $keys)
{
foreach ($keys as $k => $v) {
if (!array_key_exists($v, $array)) {
unset($keys[$k]);
}
}
return array_replace(array_flip($keys), $array);
}
Функция сравнивает два массива DOM нод и объединяет несколько перестановок в одну, что значительно ускоряет сортировку, особенно если она вызывается в процессе обновления или добавления новых элементов в список.
Вызывается функция так:
var table = document.querySelector('table tbody'); var currentList = [].slice.call(table.childNodes); var sortedList = currentList.slice().sort(function(a, b){return a.textContent > b.textContent ? 1 : -1});
sortInsertList(sortedList, currentList, table);
var sortInsertList = function(sortedList, currentList, table) {
var insertList = [], fromIndex = 0, fragmentList = null, i, item, pos, node;
for (i = 0; item = sortedList[i]; i++) {
if (currentList[i] === item) continue;
fromIndex = i;
fragmentList = document.createDocumentFragment();
while (sortedList[i] !== undefined && sortedList[i] !== currentList[i]) {
((pos = currentList.indexOf(sortedList[i], i)) !== -1) && currentList.splice(pos, 1);
currentList.splice(i, 0, sortedList[i]);
fragmentList.appendChild(sortedList[i]);
i++;
}
insertList.push({pos: fromIndex, list: fragmentList});
}
for (i = 0; item = insertList[i]; i++) {
!(node = table.childNodes[item.pos]) ? table.appendChild(item.list) : table.insertBefore(item.list, node);
}
};
Не совсем честно: если тип будет не int, то b придётся описывать на отдельной строке. Нехорошо, что идёт три обращения к элементу a[c1], но если их оптимизировать, будет длиннее. Понадеемся на компилятор.
void heapsort(int *a,int l){
int b,c,c1,p;
for(p=l/2;l>1;){
if(p==0){
b=a[--l];
a[l]=a[0];
} else b=a[--p];
for(c=p;(c1=2*c+2)<=l;с=с1){
if(c1==l || a[c1]<a[c1-1]) c1--;
if(a[c1]<b) break;
a[c]=a[c1];
}
a[c]=b;
}
}