Допустим, у меня есть этот массив:
$array = array('a'=>1,'z'=>2,'d'=>4);
Позже в скрипте я хочу добавить значение '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'
Я что-то упускаю?
$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)));
Простым подходом к этому является итерация по исходному массиву, построение нового, когда вы идете:
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 );
Согласно вашему первоначальному вопросу, лучший ответ, который я могу найти, заключается в следующем:
$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.
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, ... )
Ассоциативные массивы не упорядочены, поэтому вы можете просто добавить с помощью $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 .
Альтернативный подход заключается в дополнении ассоциативной структуры массива упорядоченным индексом, который определяет итеративный порядок ключей. Например:
$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]; }
Вы можете определить свой собственный 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]; } }
На данный момент лучше всего я могу попытаться свести к минимуму создание новых массивов, это две следующие функции:
первый пытается заменить значение в исходный массив, а второй возвращает новый массив.
// 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, )
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);
Большое использование функций массива, но как об этом проще:
Добавьте статический столбец в SQL и затем замените его в результирующем массиве. Заказ остается неизменным:
SQL:
Select pizza , drink , 'pizza-drink' as 'pizza-drink' , 28 columns..... From Table
Массив:
$result['pizza-drink'] = $result['pizza'] . $result['drink'];
Попробуй это
$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
вы можете добавить его, выполнив
$array['c']=3;
и если вы абсолютно хотите, чтобы он отсортировался для печати, вы можете использовать функцию php's ksort ($ array)
если ключи не сортируются по ksort, тогда вам придется создать свой собственный вид, используя функцию uasort php. см. примеры здесь