Reputation:
Is there a way to change all the numeric keys to "Name" without looping through the array (a native PHP function)?
[
0 => 'blabla',
1 => 'blabla',
2 => 'blblll',
// etc ...
]
Upvotes: 44
Views: 123046
Reputation: 19492
You can not have the same array key twice. You would need to use arrays/objects.
$tupels = [
[ 'item', 'blabla']
[ 'item', 'blabla']
[ 'item', 'blblll']
];
$subArrays = [
[ 'name' => 'item', value: 'blabla']
[ 'name' => 'item', value: 'blabla']
[ 'name' => 'item', value: 'blblll']
];
$dataObjects = [
new MyItemModel('blabla'),
new MyItemModel('blabla'),
new MyItemModel('blabla')
];
If your goal is an XML output - use a different viewpoint. translate/transform
would mean that you create the XML from another data format - this requires you to define that format and include or add mapping information.
For most purposes it is a lot easier to generate
a specific XML output using DOM or XMLWriter from your (known) data structures. At some point you iterate the array and create the item nodes.
With DOM it is possible to use array_map()
or iteration.
$data = [
0 => 'blabla',
1 => 'blabla',
2 => 'blblll',
// etc ...
];
$document = new DOMDocument();
$document->append(
$items = $document->createElement('items')
);
$items->append(
...array_map(
function($text) use ($document) {
$item = $document->createElement('item');
$item->textContent = $text;
return $item;
},
$data
)
);
$document->formatOutput = true;
echo $document->saveXML();
<?xml version="1.0"?>
<items>
<item>blabla</item>
<item>blabla</item>
<item>blblll</item>
</items>
append()
is a DOM LV method that was implemented in PHP 8.0. It can take nodes and strings as arguments - strings will be added as text nodes.
Using arrap_map()
allows to encapsulate the creation of child nodes into separate functions.
However a foreach()
works just fine if you do not need the separation.
$document = new DOMDocument();
$document->append(
$items = $document->createElement('items')
);
foreach ($data as $text) {
$items->append(
$item = $document->createElement('item')
);
$item->textContent = $text;
}
$document->formatOutput = true;
echo $document->saveXML();
The original method to append nodes is appendChild()
. It allows you to append a single node. append()
is just a shortcut for us lazy people.
$document = new DOMDocument();
$document->appendChild(
$items = $document->createElement('items')
);
foreach ($data as $text) {
$items->appendChild(
$item = $document->createElement('item')
);
$item->textContent = $text;
}
$document->formatOutput = true;
echo $document->saveXML();
If you need to generate large XML document, XMLWriter is another option. It directly writes into a stream.
$writer = new XMLWriter();
$writer->openMemory();
$writer->setIndent(2);
$writer->startDocument();
$writer->startElement('items');
foreach ($data as $text) {
$writer->writeElement('item', $text);
}
$writer->endElement();
$writer->endDocument();
echo $writer->outputMemory();
Upvotes: 0
Reputation: 81
This is an example prefixing all the keys with an underscore.
We use array_combine
to combine the array keys with the array values, but we first run an array_map
function on the array keys, which takes a simple function that adds the prefix.
$prefix = '_';
$arr = array_combine(
array_map(function($v) use ($prefix){
return $prefix.$v;
}, array_keys($arr)),
array_values($arr)
);
See a live example here.
Upvotes: 8
Reputation: 226
change array key name "group" to "children".
<?php
echo json_encode($data);
function array_change_key_name( $orig, $new, &$array ) {
foreach ( $array as $k => $v ) {
$res[ $k === $orig ? $new : $k ] = ( (is_array($v)||is_object($v)) ? array_change_key_name( $orig, $new, $v ) : $v );
}
return $res;
}
echo '<br>=====change "group" to "children"=====<br>';
$new = array_change_key_name("group" ,"children" , $data);
echo json_encode($new);
?>
result:
{"benchmark":[{"idText":"USGCB-Windows-7","title":"USGCB: Guidance for Securing Microsoft Windows 7 Systems for IT Professional","profile":[{"idText":"united_states_government_configuration_baseline_version_1.2.0.0","title":"United States Government Configuration Baseline 1.2.0.0","group":[{"idText":"security_components_overview","title":"Windows 7 Security Components Overview","group":[{"idText":"new_features","title":"New Features in Windows 7"}]},{"idText":"usgcb_security_settings","title":"USGCB Security Settings","group":[{"idText":"account_policies_group","title":"Account Policies group"}]}]}]}]}
=====change "group" to "children"=====
{"benchmark":[{"idText":"USGCB-Windows-7","title":"USGCB: Guidance for Securing Microsoft Windows 7 Systems for IT Professional","profile":[{"idText":"united_states_government_configuration_baseline_version_1.2.0.0","title":"United States Government Configuration Baseline 1.2.0.0","children":[{"idText":"security_components_overview","title":"Windows 7 Security Components Overview","children":[{"idText":"new_features","title":"New Features in Windows 7"}]},{"idText":"usgcb_security_settings","title":"USGCB Security Settings","children":[{"idText":"account_policies_group","title":"Account Policies group"}]}]}]}]}
Upvotes: 2
Reputation: 57354
No, there is not, for starters, it is impossible to have an array with elements sharing the same key
$x =array();
$x['foo'] = 'bar' ;
$x['foo'] = 'baz' ; #replaces 'bar'
Secondarily, if you wish to merely prefix the numbers so that
$x[0] --> $x['foo_0']
That is computationally implausible to do without looping. No php functions presently exist for the task of "key-prefixing", and the closest thing is "extract" which will prefix numeric keys prior to making them variables.
The very simplest way is this:
function rekey( $input , $prefix ) {
$out = array();
foreach( $input as $i => $v ) {
if ( is_numeric( $i ) ) {
$out[$prefix . $i] = $v;
continue;
}
$out[$i] = $v;
}
return $out;
}
Additionally, upon reading XMLWriter usage, I believe you would be writing XML in a bad way.
<section>
<foo_0></foo_0>
<foo_1></foo_1>
<bar></bar>
<foo_2></foo_2>
</section>
Is not good XML.
<section>
<foo></foo>
<foo></foo>
<bar></bar>
<foo></foo>
</section>
Is better XML, because when intrepreted, the names being duplicate don't matter because they're all offset numerically like so:
section => {
0 => [ foo , {} ]
1 => [ foo , {} ]
2 => [ bar , {} ]
3 => [ foo , {} ]
}
Upvotes: 22
Reputation: 2106
To have the same key I think they must be in separate nested arrays.
for ($i = 0; $i < count($array); $i++) {
$newArray[] = ['name' => $array[$i]];
};
Output:
0 => array:1 ["name" => "blabla"]
1 => array:1 ["name" => "blabla"]
2 => array:1 ["name" => "blblll"]
Upvotes: 1
Reputation: 1822
I added this for an answer to another question and seemed relevant. Hopefully might help someone that needs to change the value of the keys in an array. Uses built-in functions for php.
$inputArray = array('app_test' => 'test', 'app_two' => 'two');
/**
* Used to remap keys of an array by removing the prefix passed in
*
* Example:
* $inputArray = array('app_test' => 'test', 'app_two' => 'two');
* $keys = array_keys($inputArray);
* array_walk($keys, 'removePrefix', 'app_');
* $remappedArray = array_combine($keys, $inputArray);
*
* @param $value - key value to replace, should be from array_keys
* @param $omit - unused, needed for prefix call
* @param $prefix - prefix to string replace in keys
*/
function removePrefix(&$value, $omit, $prefix) {
$value = str_replace($prefix, '', $value);
}
// first get all the keys to remap
$keys = array_keys($inputArray);
// perform internal iteration with prefix passed into walk function for dynamic replace of key
array_walk($keys, 'removePrefix', 'app_');
// combine the rewritten keys and overwrite the originals
$remappedArray = array_combine($keys, $inputArray);
// see full output of comparison
var_dump($inputArray);
var_dump($remappedArray);
Output:
array(2) {
'attr_test' =>
string(4) "test"
'attr_two' =>
string(3) "two"
}
array(2) {
'test' =>
string(4) "test"
'two' =>
string(3) "two"
}
Upvotes: 6
Reputation: 37
<?php
$array[$new_key] = $array[$old_key];
unset($array[$old_key]);
?>
Upvotes: 0
Reputation: 1372
I did this for an array of objects. Its basically creating new keys in the same array and unsetting the old keys.
public function transform($key, $results)
{
foreach($results as $k=>$result)
{
if( property_exists($result, $key) )
{
$results[$result->$key] = $result;
unset($results[$k]);
}
}
return $results;
}
Upvotes: 0
Reputation:
The solution to when you're using XMLWriter
(native to PHP 5.2.x
<) is using $xml->startElement('itemName');
this will replace the arrays key.
Upvotes: 2
Reputation: 27
I think that he want:
$a = array(1=>'first_name', 2=>'last_name');
$a = array_flip($a);
$a['first_name'] = 3;
$a = array_flip($a);
print_r($a);
Upvotes: 1
Reputation:
Use array array_flip
in php
$array = array ( [1] => Sell [2] => Buy [3] => Rent [4] => Jobs )
print_r(array_flip($array));
Array ( [Sell] => 1 [Buy] => 2 [Rent] => 3 [Jobs] => 4 )
Upvotes: 0
Reputation: 2986
If you have an array of keys that you want to use then use array_combine
Given $keys = array('a', 'b', 'c', ...) and your array, $list, then do this:
$list = array_combine($keys, array_values($list));
List will now be array('a' => 'blabla 1', ...) etc.
You have to use array_values
to extract just the values from the array and not the old, numeric, keys.
That's nice and simple looking but array_values makes an entire copy of the array so you could have space issues. All we're doing here is letting php do the looping for us, not eliminate the loop. I'd be tempted to do something more like:
foreach ($list as $k => $v) {
unset ($list[$k]);
$new_key = *some logic here*
$list[$new_key] = $v;
}
I don't think it's all that more efficient than the first code but it provides more control and won't have issues with the length of the arrays.
Upvotes: 105
Reputation: 9383
You could create a new array containing that array, so:
<?php
$array = array();
$array['name'] = $oldArray;
?>
Upvotes: -4