Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Сортировка массива по определенным ключам другого массива

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
antobra
Отправлено: 19 Апреля, 2019 - 11:21:38
Post Id


Посетитель


Покинул форум
Сообщений всего: 327
Дата рег-ции: Окт. 2010  


Помог: 1 раз(а)




Коллеги, подскажите, пожайлуста, "красивое" решение следующей задачи, до которой не могу дойти самостоятельно.

Имеем большой массив с множеством ключей и значений:

PHP:
скопировать код в буфер обмена
  1. $array = [
  2.  
  3.         'key1' => [ 'somevalue' => 'somevalue', 'type' => 'red' ],
  4.         'key2' => [ 'somevalue' => 'somevalue', 'type' => 'pink' ],
  5.         'key3' => [ 'somevalue' => 'somevalue', 'type' => 'red' ],
  6.         'key4' => [ 'somevalue' => 'somevalue', 'type' => 'pink' ],
  7.         'key5' => [ 'somevalue' => 'somevalue', 'type' => 'white' ],
  8.         'key6' => [ 'somevalue' => 'somevalue', 'type' => 'blue' ],
  9.  
  10. ];
  11.  

Имеем правила сортировки, которые говорят в каком порядке должен быть $array по ключу 'type'.

PHP:
скопировать код в буфер обмена
  1. $rules = [
  2.  
  3.         'blue',
  4.         'red',
  5.         'pink'
  6.  
  7. ];


Таким образом необходимо получить:

PHP:
скопировать код в буфер обмена
  1. $array = [
  2.  
  3.         'key6' => [ 'somevalue' => 'somevalue', 'type' => 'blue' ],
  4.         'key1' => [ 'somevalue' => 'somevalue', 'type' => 'red' ],
  5.         'key3' => [ 'somevalue' => 'somevalue', 'type' => 'red' ],
  6.         'key2' => [ 'somevalue' => 'somevalue', 'type' => 'pink' ],
  7.         'key4' => [ 'somevalue' => 'somevalue', 'type' => 'pink' ],
  8.         'key5' => [ 'somevalue' => 'somevalue', 'type' => 'white' ],
  9.        
  10.  
  11. ];


Если в rules нет ключа, который есть в $array (например, white), то он помещается в конец.

Буду благодарен за помощь
 
 Top
lastdays
Отправлено: 19 Апреля, 2019 - 14:18:07
Post Id



Частый гость


Покинул форум
Сообщений всего: 220
Дата рег-ции: Март 2013  


Помог: 7 раз(а)




PHP:
скопировать код в буфер обмена
  1.  
  2. function arr_sort( $l, $r )
  3. {
  4.  
  5.        $index = array
  6.        (
  7.         'blue'  => 3,
  8.         'red'   => 2,
  9.         'pink'  => 1
  10.        );
  11.  
  12.        //- Если пусто - в конец.
  13.        if ( empty( $index[$l["type"]] ) )
  14.        {
  15.          $index[$l["type"]] = 0;
  16.        }
  17.  
  18.        //- Если пусто - в конец.
  19.        if ( empty( $index[$r["type"]] ) )
  20.        {
  21.          $index[$r["type"]] = 0;
  22.        }
  23.  
  24.        if ( $index[$l["type"]] < $index[$r["type"]] )
  25.        {
  26.          return true;
  27.        }
  28.        else if ( $index[$l["type"]] > $index[$r["type"]] )
  29.        {
  30.          return false;
  31.        }
  32.  
  33. }
  34.  
  35.  
  36. $arr = array();
  37. $arr['key1'] = array( 'somevalue' => 'somevalue', 'type' => 'white' );
  38. $arr['key2'] = array( 'somevalue' => 'somevalue', 'type' => 'blue' );
  39. $arr['key3'] = array( 'somevalue' => 'somevalue', 'type' => 'red' );
  40. $arr['key4'] = array( 'somevalue' => 'somevalue', 'type' => 'blue' );
  41. $arr['key5'] = array( 'somevalue' => 'somevalue', 'type' => 'red' );
  42. $arr['key6'] = array( 'somevalue' => 'somevalue', 'type' => 'red' );
  43. $arr['key7'] = array( 'somevalue' => 'somevalue', 'type' => 'white' );
  44. $arr['key8'] = array( 'somevalue' => 'somevalue', 'type' => 'red' );
  45.  
  46.  
  47. if ( !empty ( $arr ) )
  48. {
  49.   usort ($arr, 'arr_sort');
  50.  
  51.   foreach ( $arr as $k => $v )
  52.   {
  53.     echo ' '.$k.' => '.$v['type'].' <br />';
  54.   }
  55.   unset( $k, $v );
  56.  
  57. }
  58.  
  59. unset( $arr );
  60.  


Такой вот быдлокод, может кто лучше предложит.

(Отредактировано автором: 19 Апреля, 2019 - 14:19:13)

 
 Top
Мелкий Супермодератор
Отправлено: 19 Апреля, 2019 - 15:29:06
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




PHP:
скопировать код в буфер обмена
  1. uasort($array, function($a, $b) use($rules) {
  2.     $apos = array_search($a['type'], $rules);
  3.     $bpos = array_search($b['type'], $rules);
  4.     if ($apos !== false and $bpos !== false)
  5.         return $apos <=> $bpos;
  6.     else
  7.         return ($apos === false) <=> ($bpos === false);
  8. });
  9. var_dump($array);

php 7.0+
Имеет смысл переформатировать $rules во что-то более подходящее для поиска по значению.
(Добавление)
Мелкий пишет:
переформатировать $rules во что-то более подходящее для поиска по значению.

как-то так:
PHP:
скопировать код в буфер обмена
  1. $sortIndex = array_flip($rules);
  2. uasort($array, function($a, $b) use($sortIndex) {
  3.     $apos = $sortIndex[ $a['type'] ] ?? false;
  4.     $bpos = $sortIndex[ $b['type'] ] ?? false;
  5.     if ($apos !== false and $bpos !== false)
  6.         return $apos <=> $bpos;
  7.     else
  8.         return ($apos === false) <=> ($bpos === false);
  9. });


-----
PostgreSQL DBA
 
 Top
LIME
Отправлено: 20 Апреля, 2019 - 13:03:31
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




Мелкий дополню для таксказать синьоров
ты же знаешь что сорт реализован как quicksort?
супер что ты учел отсутствие ключа
но...тогда надо отталкиваться от предметной области
если высока вероятность многих таких значений...лучше один раз фулскан с выборкой их
сорт выдохнет облегченно
просто заметил))
 
 Top
antobra
Отправлено: 15 Мая, 2019 - 22:44:09
Post Id


Посетитель


Покинул форум
Сообщений всего: 327
Дата рег-ции: Окт. 2010  


Помог: 1 раз(а)




Коллеги, огромное спасибо. Поблагодарил через "Спасибо!" всех причастных!)
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB