Как добавить значение массива в середину ассоциативного массива?

Позволяет сказать, что у меня есть этот массив:

$array = array('a'=>1,'z'=>2,'d'=>4);

Позже в script я хочу добавить значение 'c'=>3 до 'z'. Как я могу это сделать?

EDIT: Да, порядок важен. Когда я запускаю foreach() через массив, я НЕ хочу, чтобы это добавленное добавление добавилось в конец массива. Я получаю этот массив из mysql_fetch_assoc()

EDIT 2: Ключи, которые я использовал выше, являются заполнителями. Использование ksort() не достигнет того, что я хочу.

EDIT 3: http://www.php.net/manual/en/function.array-splice.php#88896 выполняет то, что я ищу, но я ищу что-то более простое.

EDIT 4: Спасибо за downvotes. Я ответил на ваши ответы, и вы не могли помочь, поэтому вы отказались и попросили закрыть вопрос, потому что вы не знали ответа. Спасибо.

РЕДАКТИРОВАТЬ 5: Возьмите образец таблицы db с примерно 30 столбцами. Я получаю эти данные с помощью mysql_fetch_assoc(). В этом новом массиве после столбца "пицца" и "напиток" я хочу добавить новый столбец "full_dinner", который объединяет значения "пицца" и "напиток", чтобы при запуске foreach() на указанном массиве, 'full_dinner' приходит сразу после 'drink'

Ответ 1

Я что-то пропустил?

$key = 'z';
$offset = array_search($key, array_keys($array));

$result = array_merge
        (
            array_slice($array, 0, $offset),
            array('c' => 3),
            array_slice($array, $offset, null)
        );

Обработка несуществующих ключей (добавление $data по умолчанию):

function insertBeforeKey($array, $key, $data = null)
{
    if (($offset = array_search($key, array_keys($array))) === false) // if the key doesn't exist
    {
        $offset = 0; // should we prepend $array with $data?
        $offset = count($array); // or should we append $array with $data? lets pick this one...
    }

    return array_merge(array_slice($array, 0, $offset), (array) $data, array_slice($array, $offset));
}

Демо:

$array = array('a' => 1, 'z' => 2, 'd' => 4);

// array(4) { ["a"]=> int(1) ["c"]=> int(3) ["z"]=> int(2) ["d"]=> int(4) }
var_dump(insertBeforeKey($array, 'z', array('c' => 3)));

// array(4) { ["a"]=> int(1) ["z"]=> int(2) ["d"]=> int(4) ["c"]=> int(3) }
var_dump(insertBeforeKey($array, 'y', array('c' => 3)));

Ответ 2

Простым подходом к этому является итерация исходного массива, построение нового, когда вы идете:

function InsertBeforeKey( $originalArray, $originalKey, $insertKey, $insertValue ) {

    $newArray = array();
    $inserted = false;

    foreach( $originalArray as $key => $value ) {

        if( !$inserted && $key === $originalKey ) {
            $newArray[ $insertKey ] = $insertValue;
            $inserted = true;
        }

        $newArray[ $key ] = $value;

    }

    return $newArray;

}

Затем просто вызовите

$array = InsertBeforeKey( $array, 'd', 'c', 3 );

Ответ 3

Согласно вашему первоначальному вопросу, лучший ответ, который я могу найти, заключается в следующем:

$a = array('a'=>1,'z'=>2,'d'=>4);

$splitIndex = array_search('z', array_keys($a));
$b = array_merge(
        array_slice($a, 0, $splitIndex), 
        array('c' => 3), 
        array_slice($a, $splitIndex)
);

var_dump($b);
array(4) {
  ["a"]=>
  int(1)
  ["c"]=>
  int(3)
  ["z"]=>
  int(2)
  ["d"]=>
  int(4)
}

В зависимости от того, насколько велики ваши массивы, вы будете дублировать довольно некоторые данные во внутренней памяти, независимо от того, используете ли вы это решение или другое.

Кроме того, ваше пятое редактирование, похоже, указывает, что в качестве альтернативы ваш SQL-запрос может быть улучшен. То, что вы, похоже, хотите сделать, будет примерно таким:

SELECT a, b, CONCAT(a, ' ', b) AS ab FROM ... WHERE ...

Если изменение вашего оператора SELECT может привести к избыточности решения PHP, вам обязательно нужно перейти с измененным SQL.

Ответ 4

function insertValue($oldArray, $newKey, $newValue, $followingKey) {

    $newArray = array ();
    foreach (array_keys($oldArray) as $k) {
        if ($k == $followingKey)
            $newArray[$newKey] = $newValue;
        $newArray[$k] = $oldArray [$k];
    }

    return $newArray;
}

Вы называете это

insertValue($array, 'c', '3', 'z')

Что касается Edit 5:

отредактируйте свой sql, чтобы он читал

SELECT ..., pizza, drink, pizza+drink as full_meal, ... FROM ....

и у вас есть столбец автоматически:

Array (
  ...
  'pizza' => 12,
  'drink' => 5,
  'full_meal' => 17,
  ...
)

Ответ 5

Ассоциативные массивы не упорядочены, поэтому вы можете просто добавить с помощью $array['c'] = 3.

Если порядок важен, одним из вариантов является преобразование в структуру данных больше:

$array = array(
   array('a' => 1),
   array('b' => 2)
   array('d' => 4)
);

Затем используйте array_splice($array, 2, 0, array('c' => 3)) для вставки в позицию 2. См. руководство по array_splice.

Ответ 6

Альтернативный подход заключается в дополнении ассоциативной структуры массива упорядоченным индексом, который определяет итеративный порядок ключей. Например:

$index = array('a','b','d');

// Add new value and update index
$array['c'] = 3;
array_splice($index, 2, 0, 'c');

// Iterate the array in order
foreach $index as $key {
   $value = $array[$key];
}

Ответ 7

Вы можете определить свой собственный sortmap при выполнении сортировки по пузырьку по ключу. Это, вероятно, не очень эффективно, но оно работает.

<pre>
<?php

$array = array('a'=>1,'z'=>2,'d'=>4);

$array['c'] = 3;

print_r( $array );

uksort( $array, 'sorter' );

print_r( $array );

function sorter( $a, $b )
{
    static $ordinality = array(
        'a' => 1
      , 'c' => 2
      , 'z' => 3
      , 'd' => 4
    );
    return $ordinality[$a] - $ordinality[$b];
}

?>
</pre>

Здесь подход, основанный на ArrayObject с использованием этой же концепции

$array = new CitizenArray( array('a'=>1,'z'=>2,'d'=>4) );
$array['c'] = 3;

foreach ( $array as $key => $value )
{
    echo "$key: $value <br>";
}

class CitizenArray extends ArrayObject
{
    static protected $ordinality = array(
        'a' => 1
      , 'c' => 2
      , 'z' => 3
      , 'd' => 4
    );

    function offsetSet( $key, $value )
    {
        parent::offsetSet( $key, $value );
        $this->uksort( array( $this, 'sorter' ) );
    }

    function sorter( $a, $b )
    {
        return self::$ordinality[$a] - self::$ordinality[$b];
    }
}

Ответ 8

На данный момент лучше всего я могу попытаться свести к минимуму создание новых массивов, это две следующие функции:

первый пытается заменить значение в исходный массив, а второй возвращает новый массив.

// replace value into the original array
function insert_key_before_inplace(&$base, $beforeKey, $newKey, $value) {
 $index = 0;
 foreach($base as $key => $val) {
    if ($key==$beforeKey) break;
    $index++;
 }
 $end = array_splice($base, $index, count($base)-$index);
 $base[$newKey] = $value;
 foreach($end as $key => $val) $base[$key] = $val;
}


$array = array('a'=>1,'z'=>2,'d'=>4);

insert_key_before_inplace($array, 'z', 'c', 3);

var_export($array); // array ( 'a' => 1, 'c' => 3, 'z' => 2, 'd' => 4, )

// create new array
function insert_key_before($base, $beforeKey, $newKey, $value) {
 $index = 0;
 foreach($base as $key => $val) {
    if ($key==$beforeKey) break;
    $index++;
 }
 $end = array_splice($base, $index, count($base)-$index);
 $base[$newKey] = $value;
 return $base+$end;
}


$array = array('a'=>1,'z'=>2,'d'=>4);

$newArray=insert_key_before($array, 'z', 'c', 3);

var_export($array); // ( 'a' => 1, 'z' => 2, 'd' => 4, )

var_export($newArray); // array ( 'a' => 1, 'c' => 3, 'z' => 2, 'd' => 4, )

Ответ 9

function putarrayelement(&$array, $arrayobject, $elementposition, $value = null) {

        $count = 0;
        $return = array();
        foreach ($array as $k => $v) {
        if ($count == $elementposition) {
                if (!$value) {
                    $value = $count;
                }
            $return[$value] = $arrayobject;
            $inserted = true;
        }
        $return[$k] = $v;
        $count++;
        }
        if (!$value) {
           $value = $count;
        }
        if (!$inserted){
            $return[$value];
        }
        $array = $return;
       return $array;
     }

        $array = array('a' => 1, 'z' => 2, 'd' => 4);
        putarrayelement($array, '3', 1, 'c');
        print_r($array);

Ответ 10

Большое использование функций массива, но как об этом проще:

Добавьте статический столбец в SQL и затем замените его в результирующем массиве. Заказ остается неизменным:

SQL:

Select pizza , drink , 'pizza-drink' as 'pizza-drink' , 28 columns..... From Table

Массив:

$result['pizza-drink'] = $result['pizza'] . $result['drink'];

Ответ 11

Упрощенная функция Alix Axel, если вам нужно просто вставить данные в n-ю позицию:

function array_middle_push( array $array, int $position, array $data ): array {
   return array_merge( array_slice( $array, 0, $position ), $data, array_slice( $array, $position ) );
}

Ответ 12

Попробуйте это

$array['c']=3;

Ассоциативный массив по умолчанию не упорядочен, но если вы хотите отсортировать их по алфавиту, вы можете использовать ksort() для сортировки массива по его ключу.

Если вы посмотрите статью PHP для ksort(), вам будет легко отсортировать массив по его ключу, например:

<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

// The above example will output:
a = orange
b = banana
c = apple
d = lemon

Ответ 13

вы можете добавить его, выполнив

$array['c']=3;

и если вы хотите, чтобы он был отсортирован для печати, вы можете использовать функцию php ksort ($ array)

если ключи не сортируются по ksort, тогда вам нужно будет создать свой собственный вид, используя функцию php uasort. см. примеры здесь

http://php.net/manual/en/function.uasort.php