Функция array_unique()
получает все уникальные значения из массива, шпонкой их первого появления.
Функция array_diff()
позволяет удалять значения из одного массива, находящегося внутри другого массива.
В зависимости от того, как вам нужно (или не иметь) результат ключа или порядок сохраненных ключей, вам нужно выполнить несколько шагов. Как правило, он работает в следующих параграфах (с примерами кода PHP):
В массиве у вас есть N
элементы, из которых Nu
уникальны.
$N = array(...);
$Nu = array_unique($N);
Число случайных элементов r
вам нужно то, чтобы заменить дубликаты являются подсчет N
минус отсчет Nu
. Поскольку подсчет N
обычно полезное значение, я также назначить его nc
:
$nc = count($N);
$r = $nc - count($Nu);
Это делает r
целое число в диапазоне от 0
до count(N) - 1
:
0 : no duplicate values/all values are unique
1 : one duplicate value/all but one value are unique
...
count(N) - 1 : all duplicate values/no unique value
Таким образом, в случае, если вам нужно ноль случайные значения ($r === 0
), результат $N
. Это граничное условие является вторым самым простым результатом (первый простой результат - входной массив без членов).
Для всех остальных случаев вам нужны r
случайные уникальные значения. В вашем вопросе вы пишете от 0 до 35. Однако это не может быть полная история. Представьте, что ваш входной массив имеет 36 дублированных значений, каждый номер в диапазоне от 0 до 35 дублируется один раз. Добавление случайных чисел из диапазона от 0 до 35 снова в массив приведет к созданию дубликатов снова - гарантировано.
Вместо этого я прочитал ваш вопрос, что вы просто ищете уникальные значения, которые еще не являются частью входного массива.
Таким образом, вы не только вам нужно r
случайные значения (Nr
), но они также не должны быть частью N
или Nu
до сих пор.
Для этого вам нужно только создать count(N)
уникальные значения, удалить из них уникальные значения Nu
, чтобы гарантировать, что ничто не дублирует значения в Nu
. Поскольку это теоретический максимум, а не точное количество, которое необходимо, что массив используется для получения среза ровно r
элементов из:
$Nr = array_slice(array_diff(range(0, $nc - 1), $Nu), 0, $r);
Если вы хотите, чтобы эти новые значения будут добавлены перемешиваются в range(0, $nc - 1)
упорядочен , вы можете сделать следующее:
shuffle($Nr);
Это должно принести хаотичность вы , кажется попросить ваш вопрос обратно в ответ.
То, что сейчас оставляет вас с уникальными частями исходного массива $Nu
и r
новых значений в $Nr
. Объединение обоих этих массивов даст вам результирующий массив, который игнорирует ключ => значение отношения (массив Переиндексирование):
array_merge($Nu, $Nr);
Например с примерным array(3, 4, 2, 1, 4, 0, 5, 0, 3, 5)
для $N
, результат это дает это:
Array
(
[0] => 3
[1] => 4
[2] => 2
[3] => 1
[4] => 0
[5] => 5
[6] => 7
[7] => 9
[8] => 6
[9] => 8
)
Как видите, все уникальные значения (0-5) начинаются с новых значений (6-9). Исходные ключи не сохраняются, например. ключом значения 5
был 6
первоначально, теперь это 5
.
Отношение или значение ключа => не сохраняются из-за array_merge()
, оно переустанавливает числовые клавиши. Также рядом с уникальными номерами в Nr
ключи также должны быть уникальными в массиве. Таким образом, для каждого нового номера, добавляемого к незанятым существующим номерам, необходимо использовать ключ, который был ключом для дублирующего номера. Для того, чтобы получить все ключи дублирующих номеров наборов ключей в исходном массиве уменьшается набором ключей всех для матчей дублирующих номеров (ключей в «уникальном массиве» $Nu
):
$Kr = array_keys(array_diff_assoc($N, $Nu));
Существующего результат $Nr
теперь можно вводить с помощью этих клавиш. Функция в PHP, чтобы установить все ключи массива является использование функции array_combine()
:
$Nr = array_combine($Kr, $Nr);
Это позволяет получить результат с ключевыми => стоимостных отношений, сохраняемых с помощью накидной оператора массива (+
):
$Nu + $Nr;
, например, с $N
из последнего примера, результат это дает это:
Array
(
[0] => 3
[1] => 4
[2] => 2
[3] => 1
[5] => 0
[6] => 5
[4] => 8
[7] => 6
[8] => 9
[9] => 7
)
Как теперь вы можете видеть, для значения 5
это ключ 6
было сохранено, а также для значения 0
, который имел ключ 5
в исходном массиве, и теперь, а на выходе вместо ключа 4
, как и в предыдущем примере ,
Однако, поскольку теперь ключи сохранены для первых вхождений исходных значений, порядок все еще изменяется: сначала все ранее уникальные значения, а затем все новые значения. Однако вы можете добавить новые значения. Для этого вам нужно получить порядок исходных ключей для новых значений. Это можно сделать путем сопоставления заказа по ключу и использования array_multisort()
для сортировки на основе этого заказа.
Поскольку это требует прохождения через возвращаемые значения параметров, это требует дополнительных, временные переменные, которые я выбрал, чтобы ввести начиная с буквы V:
// the original array defines the order of keys:
$orderMap = array_flip(array_keys($N));
// define the sort order for the result with keys preserved
$Vt = $Nu + $Nr;
$order = array();
foreach ($Vt as $key => $value) {
$order[] = $orderMap[$key];
}
Затем делается сортировкой (здесь с сохранением ключи):
// sort an array by the defined order, preserve keys
$Vk = array_keys($Vt);
array_multisort($order, $Vt, $Vk);
результат затем:
array_combine($Vk, $Vt);
Опять с примерами значений сверху:
Array
(
[0] => 3
[1] => 4
[2] => 2
[3] => 1
[4] => 7
[5] => 0
[6] => 5
[7] => 8
[8] => 6
[9] => 9
)
Этот пример показывает выход красиво, что ключи упорядочены от 0 до 9, как они были хорошо во входном массиве. По сравнению с предыдущим выходом вы можете, например, увидеть, что первое добавленное значение 7
(keyed 4
) находится на 5-й позиции - то же самое, что и значение 4
в исходном массиве. Также был получен порядок ключей.
Если это результат, к которому вы стремитесь, вы можете сократить путь к этому шагу, повторив исходные ключи массивов, и в случае, если каждый из этих ключей не является первым значением любого повторяющегося значения, вы можете поп от новых значений массива вместо:
$result = array();
foreach ($N as $key => $value) {
$result[$key] = array_key_exists($key, $Nu) ? $Nu[$key] : array_pop($Nr);
}
Опять примере массив значений результат (зависит от предыдущего, потому что $Nr
перемешивается:
Array
(
[0] => 3
[1] => 4
[2] => 2
[3] => 1
[4] => 7
[5] => 0
[6] => 5
[7] => 8
[8] => 9
[9] => 6
)
Который в конце концов, может быть, самый простой способ ответить на ваши вопрос. Надеюсь, что эта помощь вы отвечаете на вопрос. Имейте в виду следующее:
- разделите вашу проблему:
- вы хотите знать, является ли значение уникального мировоззрения или нет -
array_unique()
поможет вам здесь.
- Вы хотите создать X уникальные номера/значения.
array_diff()
помогает вам здесь.
- выравнивание потока:
- получить уникальные номера в первую очередь.
- сначала получите новые номера.
- использовать как для обработки исходного массива.
как в этом примере:
// original array
$array = array(3, 4, 2, 1, 4, 0, 5, 0, 3, 5);
// obtain unique values (1.)
$unique = array_unique($array);
// obtain new unique values (2.)
$new = range(0, count($array) - 1);
$new = array_diff($new, $unique);
shuffle($new);
// process original array (3.)
foreach ($array as $key => &$value) {
if (array_key_exists($key, $unique)) {
continue;
}
$value = array_pop($new);
}
unset($value, $new);
// result in $array:
print_r($array);
Который затем (в качестве примера из shuffle($new)
) выходы:
Array
(
[0] => 3
[1] => 4
[2] => 2
[3] => 1
[4] => 9
[5] => 0
[6] => 5
[7] => 8
[8] => 7
[9] => 6
)
Short and sweet +1 –