У меня есть следующий сценарий, состоящий из массивов с числовыми ключами. Мне нужен массив, в котором хранятся все значения массивов, сгруппированные по числовому ключу и без дубликатов. Я не могу сделать их строками, поскольку они являются идентификаторами и должны оставаться числовыми.
Отправная точка:
Array
(
[77] => Array
(
[0] => Bold Condensed
[1] => Bold Condensed 2
[2] => Bold Condensed 3
)
)
Array
(
[77] => Array
(
[0] => Bold Condensed
)
[136] => Array
(
[0] => Regular
)
)
Array
(
[77] => Array
(
[0] => Bold Condensed (1, 2, 3)
)
[168] => Array
(
[0] => Regular
[1] => Bold
)
)
Ожидаемый результат:
Array
(
[77] => Array
(
[0] => Bold Condensed
[1] => Bold Condensed 2
[2] => Bold Condensed 3
[3] => Bold Condensed (1 ,2 ,3)
)
[136] => Array
(
[0] => Regular
)
[168] => Array
(
[0] => Regular
[1] => Bold
)
)
Пробовал array_merge и array_merge_recursive:
$megaArray = [];
foreach( $arrays as $key => $value) {
if (array_key_exists($key, $arrays)){
$megaArray[$key] = array_merge_recursive($value);
}
}
Что я получаю как с array_merge, так и с array_merge_recursive:
Array
(
[77] => Array
(
[0] => Bold Condensed (1, 2, 3)
)
[136] => Array
(
[0] => Regular
)
[168] => Array
(
[0] => Regular
[1] => Bold
)
)
Кажется, что и array_merge(), и array_merge_recursive() хранят последнее значение для каждого ключа.
@ilariaroglieri В ваш вопрос и приведенный выше код встроено противоречие: вы сначала говорите о массивах, а в стартовом коде показаны три отдельных массива. Но затем ваше предложение foreach перебирает структуру $arrays, которая, похоже, состоит из данных трех массивов. Что это такое? Три массива или один массив с тремя вложенными массивами?






Я думаю, вам просто нужна комбинация array_merge и array_unique (поскольку я отмечаю, что у вас нет дубликатов в ваших листовых массивах):
$megaArray = [];
foreach ($arrays as $subArray) {
foreach ($subArray as $key => $value) {
if (array_key_exists($key, $megaArray)) {
$megaArray[$key] = array_unique(array_merge($megaArray[$key], $value));
} else {
$megaArray[$key] = $value;
}
}
}
Судя по ожидаемому результату, вам нужно одновременно проверить ключ и значения. Я пишу код, который создает точный выходной массив, подобный вашему образцу. Нет нужды говорить, что с помощью функции можно упростить весь процесс, но для понимания принципа ситуации я каждый раз повторяю foreach.
$newarray = array();
//-------------
$array1 = array();
$array1[77][0] = 'Bold Condensed';
$array1[77][1] = 'Bold Condensed 2';
$array1[77][2] = 'Bold Condensed 3';
foreach($array1 as $key => $value) {
if (array_key_exists($key, $newarray)) {
foreach($value as $subkey => $subvalue) {
if (!array_key_exists($subkey, $newarray[$key])) {
$newarray[$key][$subkey] = $subvalue;
} elseif (array_key_exists($subkey, $newarray[$key]) and $subvalue != $newarray[$key][$subkey]) {
$newkey = count($newarray[$key]);
$newarray[$key][$newkey] = $subvalue;
}
}
} else {
$newarray[$key] = $value;
}
}
//-------------
$array2 = array();
$array2[77][0] = 'Bold Condensed';
$array2[136][0] = 'Regular';
foreach($array2 as $key => $value) {
if (array_key_exists($key, $newarray)) {
foreach($value as $subkey => $subvalue) {
if (!array_key_exists($subkey, $newarray[$key])) {
$newarray[$key][$subkey] = $subvalue;
} elseif (array_key_exists($subkey, $newarray[$key]) and $subvalue != $newarray[$key][$subkey]) {
$newkey = count($newarray[$key]);
$newarray[$key][$newkey] = $subvalue;
}
}
} else {
$newarray[$key] = $value;
}
}
//-------------
$array3 = array();
$array3[77][0] = 'Bold Condensed (1, 2, 3)';
$array3[168][0] = 'Regular';
$array3[168][1] = 'Bold';
foreach($array3 as $key => $value) {
if (array_key_exists($key, $newarray)) {
foreach($value as $subkey => $subvalue) {
if (!array_key_exists($subkey, $newarray[$key])) {
$newarray[$key][$subkey] = $subvalue;
} elseif (array_key_exists($subkey, $newarray[$key]) and $subvalue != $newarray[$key][$subkey]) {
$newkey = count($newarray[$key]);
$newarray[$key][$newkey] = $subvalue;
}
}
} else {
$newarray[$key] = $value;
}
}
//Final result
print('<pre>'.print_r($newarray, true).'</pre>');
array_merge_recursive не требуется, поскольку для каждого идентификатора существует только 1 уровень, и ваш array_key_exists всегда будет истинным, поскольку вы получаете один и тот же ключ из foreach и проверяете один и тот же массив.
Вы можете сразу получить значения на основе id (в вашем случае это 77 и т. д.) и продолжать объединять значения. Позже вы сможете array_unique использовать их только один раз для повышения эффективности и получать только уникальные значения для каждого идентификатора.
<?php
$result = [];
foreach($d as $subs){
foreach($subs as $id => $values){
$result[ $id ] = array_merge($result[ $id ] ?? [], $values);
}
}
$result = array_map(fn($v) => array_unique($v), $result);
print_r($result);
foreach ($arrays as $array) {
foreach ($array as $key => $values) {
$result[$key] = array_unique(array_merge($result[$key] ?? [], ...[ $values ]));
}
}
Ответы, содержащие только код, упускают возможность обучать и расширять возможности тысяч будущих исследователей.
вот код
<?php
// Given arrays
$array1 = [
77 => ['Bold Condensed', 'Bold Condensed 2', 'Bold Condensed 3'],
];
$array2 = [
77 => ['Bold Condensed'],
136 => ['Regular'],
];
$array3 = [
77 => ['Bold Condensed (1, 2, 3)'],
168 => ['Regular', 'Bold'],
];
// Function to merge arrays
function mergeArrays(...$arrays)
{
$result = [];
foreach ($arrays as $array) {
foreach ($array as $key => $values) {
if (!isset($result[$key])) {
$result[$key] = $values;
} else {
// Merge values, removing duplicates
$result[$key] = array_values(array_unique(array_merge($result[$key], $values)));
}
}
}
return $result;
}
// Merge the arrays
$mergedArray = mergeArrays($array1, $array2, $array3);
// Output the merged array
print_r($mergedArray);
?>
Функция mergeArrays принимает несколько массивов в качестве аргументов и объединяет их в один массив результатов. Он перебирает каждый массив, объединяя значения для каждого ключа и удаляя дубликаты.
Чтобы избежать более дорогостоящих вызовов array_merge() и array_unique() на каждой итерации вложенного цикла, поддерживайте временный массив поиска и помещайте в массив результатов только уникальные значения. Другими словами, не создавайте беспорядок в коде, чтобы потом его можно было навести порядок.
Код: (Демо)
$result = [];
foreach ($arrays as $set) {
foreach ($set as $id => $row) {
foreach ($row as $value) {
if (!isset($lookup[$id][$value])) {
$lookup[$id][$value] = $value;
$result[$id][] = $value;
}
}
}
}
var_export($result);
Выход:
array (
77 =>
array (
0 => 'Bold Condensed',
1 => 'Bold Condensed 2',
2 => 'Bold Condensed 3',
3 => 'Bold Condensed (1, 2, 3)',
),
136 =>
array (
0 => 'Regular',
),
168 =>
array (
0 => 'Regular',
1 => 'Bold',
),
)
Это условие:
array_key_exists($key, $arrays)всегда будет истинным внутри вашего циклаforeach, потому что$arrays— это то, что вы повторяете. Кроме того, поскольку вы передаете только один массив вarray_merge_recursive, он просто возвращает его, а не объединяет с чем-либо.