2015-01-11 2 views
1

У меня есть 2 массива, в которых элементы из 3 групп перемешаны. Решающие ключи массивов являются: group_id и item_order:Слияние массивов, группировка и сортировка значений

$one = array(
      array('group_id' => 1, 'name' => 'Luke', 'item_order' => 0), 
      array('group_id' => 2, 'name' => 'Vader', 'item_order' => 1), 
      array('group_id' => 1, 'name' => 'Han', 'item_order' => 1) 
     ); 

$two = array(
      array('group_id' => 3, 'name' => 'Jabba', 'item_order' => 1), 
      array('group_id' => 3, 'name' => 'Palpatine', 'item_order' => 0), 
      array('group_id' => 2, 'name' => 'Bib Fortuna', 'item_order' => 0) 
     ); 

Я хотел бы:

  1. сливаются оба массива, так что результат группируется по group_id
  2. сортировать по group_id по возрастанию
  3. , наконец, сортировать каждую группу по item_order восходящая

Результат должен выглядеть следующим образом:

array(
    ['group_1'] => array(
       array('group_id' => 1, 'name' => 'Luke', 'item_order' => 0), 
       array('group_id' => 1, 'name' => 'Han', 'item_order' => 1) 
      ); 
    ['group_2'] => array(
       array('group_id' => 2, 'name' => 'Palpatine', 'item_order' => 0), 
       array('group_id' => 2, 'name' => 'Vader', 'item_order' => 1) 
      ); 
    ['group_3'] => array(
       array('group_id' => 3, 'name' => 'Bib Fortuna', 'item_order' => 0), 
       array('group_id' => 3, 'name' => 'Jabba', 'item_order' => 1) 
      ); 
    ); 

Я пытался array_merge() но все, что я в какой-то момент получает данные перезаписываются (как ключи массива являются строками) и результат не целое.

Любые идеи, как сделать это умным способом?

ответ

0

Не уверен, что самое лучшее решение возможно, но оно работает.

(1) Создание временных массивов:

$one_tmp = array(); 
$two_tmp = array(); 

(2) Оберните каждую строку в строку ключа типа, основанный на group_id в строке и, поэтому группы могут быть впоследствии объединены:

for ($i = 0; $i < count($one); $i++) { 
    $group_id = $one[$i]['group_id']; 
    $one_tmp['group_'.$group_id][$i] = $one[$i]; 
} 

for ($i = 0; $i < count($two); $i++) { 
    $group_id = $two[$i]['group_id']; 
    $two_tmp['group_'.$group_id][$i] = $two[$i]; 
} 

(3) Объединить массивы сгруппированных временные рекурсивно:

$merged = array_merge_recursive($drugs_tmp, $subdrugs_tmp); 

(4) Сортировать по группе ключей, созданных в пункте (2):

ksort($merged, SORT_NATURAL); 

(5) Сортировать каждую группу по item_order:

foreach ($merged as $key => $value) { 
    usort($merged[$key], 'compare_item_order'); 
} 

function compare_item_order($a, $b) { 
    return $a['item_order'] - $b['item_order']; 
} 

И вуаля! $merged теперь именно то, что я хотел.

+0

Последний вид (5) не работает. – bbankowski

3

Вы можете сделать это довольно легко, используя Ouzo Goodies library.

Объединить ваши массивы:

$array = array_merge($one, $two); 

Сортировать по item_order (после этого становится легче):

usort($array, function($a, $b) { 
    return $a['item_order'] > $b['item_order'] ? 1 : -1; 
}); 

Группа она (узо Goodies приходит играть):

$result = Arrays::groupBy($array, function($element) { 
    return $element['group_id']; 
}); 

Поскольку вы хотите, чтобы ключи находились в формате group_number, нам необходимо их изменить:

$result = Arrays::mapKeys($result, function($key) { 
    return 'group_' . $key; 
}); 

И это должно сделать трюк. Если вы не хотите добавлять новую библиотеку в свой стек, вы можете посмотреть исходный код и захватить эти функции на свою кодовую базу (лицензия MIT).

+0

Да, это интересно, но я больше искал решение ванили-PHP. Спасибо, в любом случае. – lesssugar

Смежные вопросы