2015-05-25 2 views
1

У меня есть этот массив (это просто его часть). 6 = идентификатор вопроса, optionIDs = возможные ответы.Array_map, когда элементы перетасовываются

Array 
(
    [3] => Array 
     (
     [0] => 6 
     [1] => Array 
      (
       [0] => Array 
        (
         [optionID] => 16 
         [isCorrect] => 0 
        ) 

       [1] => Array 
        (
         [optionID] => 14 
         [isCorrect] => 1 
        ) 

       [2] => Array 
        (
         [optionID] => 15 
         [isCorrect] => 0 
        ) 

       [3] => Array 
        (
         [optionID] => 17 
         [isCorrect] => 0 
        ) 

      ) 

    ) 

[7] => Array 
    (
     [0] => 6 
     [1] => Array 
      (
       [0] => Array 
        (
         [optionID] => 16 
         [isCorrect] => 0 
        ) 

       [1] => Array 
        (
         [optionID] => 15 
         [isCorrect] => 0 
        ) 

       [2] => Array 
        (
         [optionID] => 17 
         [isCorrect] => 0 
        ) 

       [3] => Array 
        (
         [optionID] => 14 
         [isCorrect] => 1 
        ) 

      ) 

    ) 

) 

Я пытаюсь объединить избыточные вопросы (6 и 6) с array_map:

$unique = array_map('unserialize', array_unique(array_map('serialize', $quizQuestionArray))); 

И это работает, пока optionIDs находятся в том же порядке. Но в некоторых случаях (например, здесь) они перетасовываются (16,14,15,17) (16,15,17,14). Есть ли способ их перетасовать и удалить повторяющиеся вопросы?

ответ

2

array_map-serialize - довольно грубый способ дедупликации массива. Вместо этого вы должны использовать что-то вроде этого:

$dupeIds = []; 
$array = array_filter($array, function ($item) use (&$dupeIds) { 
    $keep = !isset($dupeIds[$item[0]]); 
    $dupeIds[$item[0]] = true; 
    return $keep; 
}); 
+0

Это действительно умное решение. +1 – Federkun

+0

+1. Конечно, он возвращает те, которые должны исчезнуть - получить остальное: $ remove =! Isset ($ dupeIds [$ item [0]]); – Tompo

+0

@ user3385195 Справа исправлена ​​ошибка. – deceze

1

Вам необходимо будет отсортировать их по тому же заказу, прежде чем применять функцию array_map(). Вы можете использовать функцию uasort() и поставить свою собственную функцию сравнения, как это:

// Example array 
$array = array(
    3 => array(
     0 => 6, 
     1 => array(
      0 => array(
       'optionID' => 16, 
       'isCorrect' => 0 
      ), 
      1 => array(
       'optionID' => 14, 
       'isCorrect' => 1 
      ), 
      2 => array(
       'optionID' => 15, 
       'isCorrect' => 0 
      ), 
      3 => array(
       'optionID' => 17, 
       'isCorrect' => 0 
      ), 
     ) 
    ), 
    7 => array(
     0 => 6, 
     1 => array(
      0 => array(
       'optionID' => 16, 
       'isCorrect' => 0 
      ), 
      1 => array(
       'optionID' => 15, 
       'isCorrect' => 0 
      ), 
      2 => array(
       'optionID' => 17, 
       'isCorrect' => 0 
      ), 
      3 => array(
       'optionID' => 14, 
       'isCorrect' => 1 
      ), 
     ) 
    ) 
); 

// You can supply parts of an array to uasort() 
// uasort() will modify your array but keep your keys. 
uasort($array[3][2], 'sort_by_optionid'); 
uasort($array[7][3], 'sort_by_optionid'); 

function sort_by_optionid($a, $b) { 
    if ($a['optionID'] === $b['optionID']) { 
     return 0; 
    } else if ($a['optionID'] > $b['optionID']) { 
     return 1; 
    } else { 
     return -1; 
    } 
} 
// Done. 

Теперь ключи сохраняются, и вы можете легко array_map(), чтобы найти дубликаты, а затем сортировать снова вернуться в исходное состояние, в соответствии с ключи. Например. с uksort()

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