Array_map, когда элементы тасуются

1

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

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)));

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

Теги:
shuffle
array-map

2 ответа

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
  • 0
    +1. Конечно, он возвращает те, которые должны быть удалены - чтобы получить остальное: $ remove =! Isset ($ dupeIds [$ item [0]]);
Показать ещё 1 комментарий
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()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню