Я хочу объединить 2 массива, но я хочу, чтобы порядок элементов основывался на значении индекса, которое хранится в другом массиве.
$old = array("aaa", "ccc", "ddd");
$oldPos = array(0, 2, 3);
$new = array("bbb", "eee");
$combinedArr = //This is where I need help combining the $old and $new based on the logic explained below.
$oldPos
содержит порядковый номер, соответствующий каждому элементу в $old
массив. Таким образом, в этом примере «aaa» будет в индексе 0 нового массива, «ccc» будет в индексе 2, а «ddd» будет в индексе 3.
$ комбинированный Arr должен распечатать:
"aaa", "bbb", "ccc", "ddd", "eee"
Надеюсь, что это будет полезно.
Попробуйте этот фрагмент кода здесь
<?php
ini_set('display_errors', 1);
$old = array("aaa", "ccc", "ddd");
$oldPos = array(0, 2, 3);
$new = array("bbb", "eee");
$count=count($old)+count($new); // count of the no of elements of both the array.
$arrayFlip= array_flip($oldPos);//flipping the array over values
$combined=array();
for($x=0;$x<$count;$x++)
{
if(isset($arrayFlip[$x]))
{
$combined[$x]= current($old);//using current element of array
unset($old[key($old)]);//unsetting current element of array
}
else
{
$combined[$x]= current($new);//using current element of array
unset($new[key($new)]);//unsetting current element of array
}
}
print_r($combined);
Ты можешь использовать array_combine
. Для значений просто склейте два массива вместе с array_merge
. Для ключей, во-первых, получите весь диапазон результирующего размера массива, используя range
, затем удалите взятые ключи (те из
$oldPos
) с array_diff
. И еще раз склеиваем $oldPos
и итоговая разница. Этот массив будет вашими позициями. В конце концов, вы можете отсортировать массив по ключам, используя ksort
$old = array("aaa", "ccc", "ddd");
$oldPos = array(0, 2, 3);
$new = array("bbb", "eee");
$combinedArr = array_combine(
array_merge(
$oldPos,
// Deduce keys for new array elements substacting $oldPos
// from the whole range
array_diff(range(0, count($old) + count($new) -1), $oldPos)
),
array_merge($old, $new)
);
ksort($combinedArr);
Вот рабочая демо.
Такой подход избавляет вас от использования явных циклов (что, если вы не человек, занимающийся микрооптимизацией, — отличная вещь) и гарантирует, что вы извлекаете как можно больше из стандартной библиотеки PHP.
Это зависит от того, все ли массивы отсортированы правильно (хотя я думаю, что это предел того, что вы пытаетесь сделать в любом случае)
<?php
$old = ["aaa", "ccc", "ddd"];
$oldPos = [0, 2, 3];
$new = ["bbb", "eee"];
$combinedArr = [];
$i = 0;
// Keep looping until we've exhausted both arrays
while (count($old) + count($new) > 0) {
// If $i matches an entry in $oldPos, grab the entry from $old, otherwise from $new
$combinedArr[] = in_array($i, $oldPos) ? array_shift($old) : array_shift($new);
$i++;
}
print_r($combinedArr); // ["aaa", "bbb", "ccc", "ddd", "eee"]
Попробуй это:
$old = array("aaa", "ccc", "ddd");
$oldPos = array(0, 2, 3);
$new = array("bbb", "eee");
$oldKeys = array_combine($oldPos, $old);
foreach ($new as $key => $val) {
$curKey = $key;
while (isset($oldKeys[$curKey])) {
$curKey++;
}
$oldKeys[$curKey] = $val;
}
sort($oldKeys);
var_dump($oldKeys);
Держите телефон, я нашел более прямой подход с помощью array_multisort()
это означает, что вам не нужно соединять объединенные ключи с объединенными значениями. Это использует 6 вызовов функций по сравнению с 7-функциональным методом, который я прокомментировал под ответом Севавиетла.
Я изменил значения в old
а также new
массивы, чтобы отличить, что выходной массив не упорядочен по алфавиту (примерные данные OP могут вызвать некоторую путаницу у будущих читателей).
Демонстрация № 1: многословный стиль
$oldvals = array("Last", "Fourth", "Second");
$oldkeys = array(4, 3, 1);
$newvals = array("First", "Third");
$vals=array_merge($oldvals,$newvals); // forge one array with old elements first and new elements second
$newkeys=array_diff(range(0,sizeof($vals)-1),$oldkeys); // generate all necessary keys, omit "old" keys
$keys=array_merge($oldkeys,$newkeys); // forge one array with old keys first and new keys second (as values)
array_multisort($keys,$vals); // sort unordered keys and unordered vals in the same fashion
var_export($vals);
Демонстрация № 2: сжатый стиль
$oldvals=['First','Third','Fourth'];
$oldkeys=[0,2,3];
$newvals=['Second','Last'];
$vals=array_merge($oldvals,$newvals);
array_multisort(array_merge($oldkeys,array_diff(range(0,sizeof($vals)-1),$oldkeys)),$vals);
var_export($vals);
Вывод из любого блока кода:
array (
0 => 'First',
1 => 'Second',
2 => 'Third',
3 => 'Fourth',
4 => 'Last',
)
Вот зацикливание for
метод цикла, который не сломается на неупорядоченном $oldkeys
ценности. Демонстрация с проверкой данных OP и неупорядоченных данных
$oldvals = array("Last", "Fourth", "Second");
$oldkeys = array(4, 3, 1);
$newvals = array("First", "Third");
for($i=0, $count=sizeof($oldvals)+sizeof($newvals); $i<$count; ++$i){
$result[$i]=(($k=array_search($i,$oldkeys))!==false?$oldvals[$k]:array_shift($newvals));
}
var_export($result); // same result as my earlier method