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

245
10 марта 2017, 00:48

Стала задача отсортировать массив, приходящий из БД. Один элелемент из этого массива выглядит так:

Array ( [id] => 261 [category] => 1 [subcategory] => 83 [name] => Гель-краска 10 г цвет 02 [name_tr] => [description] =>[description_tr] =>[price-usd] => [price-usd-promo] => [price-try] => [price-try-promo] => [price-rub] => [price-rub-promo] => [image] => 02в.jpg [sku] => [status] => 1 [novelty] => [recommended] => [promo] => [sales] => [hits] => [type] => 2 [volume] => [width] => [height] => [thickness] => [weight] => [material] => [abrasiveness] => [seo_title] => [seo_description] => [seo_keywords] => ) 

Надо отсортировать этот массив по полю name по возрастанию. Имена для одной категории не меняются, но меняются для иной. В конце обязательно стоит число вида

01, 02, 021

Можно выполнить сортировку при SQL-запросе

$sql ="SELECT * FROM c_products WHERE category = '".$category[0]['id']."' AND status = '1' AND subcategory = '".$subcategory[0]['id']."' ORDER BY name ASC LIMIT $offset,$num ";

При существующей сортировке выводится следующим образом

01, 011, 012, 02, 020

Answer 1

Для сортировки данных в php можно воспользоваться функцией usort

$data = [
  ['id' => 1, 'name' => 'Name qweqweqwe 17'],
  ['id' => 3, 'name' => 'Name qweqweqwe 09'],
  ['id' => 4, 'name' => 'Name qweqweqwe 2'],
  ['id' => 5, 'name' => 'Name qweqweqwe 15'],
  ['id' => 7, 'name' => 'Name qweqweqwe 021'],
  ['id' => 9, 'name' => 'Name qweqweqwe 8'],
];
usort($data, function($a, $b){
  $a = explode(' ', $a['name']);
  $b = explode(' ', $b['name']);
  return array_pop($a) - array_pop($b);
});
print_r($data);

3v4l.org

Answer 2

Структуру данных нужно менять. Предложу план безболезненного перехода.

Миграция данных

  • Заведите новые колонки для значимых данных (title, weight, color)
  • Напишите скрипт, который разбирает name и заполняет новые поля.

Поддержание консистенции

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

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

Answer 3

Предлагаю так: заводите массив в который будете помещать все полученные из БД данные и массив для кода цвета. Все полученные данные перебираете и name режете на куски. Т.к. в конце всегда стоит нужный нам для сортировки номер, то получаем его и заносим во второй массив для кода цвета, а все данные в первый массив. Далее уже сортируем наш новый массив с помощью другого массива и работаем с ним. Примерно вот так (тут просто для одного name):

$global_array=[]; //Глобальный массив в который помщаем все данных из запроса и цвет отдельной переменной
$sorting_values=[]; //значния для сортировки - код цвета
$name='Гель-краска 10 г цвет 02';
$name_arr=explode(' ', $name); //режем name на части по пробелу
$сolor=array_pop($name_arr); //получаем последнюю часть массива с кусками name, т.е. код цвета
$global_array[]=$name; //заносим нужные данные в глобальный массив (все переменные из запроса). НО ключи - цифры по порядку! Вам тут скорее всего нужно будет завести многомерный массив
$sorting_values[]=$сolor; //код цвета в отдельный массив. Ключи тоже цифры по порядку. Они должны совпадать с указанными в $global_array

array_multisort($sorting_values, $global_array); //сортируем массив global_array по sorting_values
print_r($global_array);
READ ALSO
Добавить CDATA в xml?

Добавить CDATA в xml?

Как в первом случае обновить в элементе offer_text секцию <![CDATA[ ]]> на содержимое переменной $text, а во втором добавить ее?

222
Валидация входящих данных Yii по integer

Валидация входящих данных Yii по integer

Вечер добрый, не получается сделать валидацию входящих данных в Yii2, в модели пишу правило, но вылетает исключение

258
Кнопка &ldquo;Назад&rdquo; и кнопка &ldquo;Загрузить ещё&rdquo; на Ajax

Кнопка “Назад” и кнопка “Загрузить ещё” на Ajax

В интернет-магазине на странице категории добавил сортировку товаров и кнопку "Загрузить ещё", но если нажать на товар, а потом на кнопку назад...

259
Как запретить доступ к админке

Как запретить доступ к админке

В app/Http/Authenticatephp добавил такой код

254