I am needing to rename dynamic array keys, and create a new array.
Here is the array as given:
array(21)
{
["0161"] =>
array(5)
{
["L_NAME0161"] =>
string(13) "john%20Hewett"
["L_TRANSACTIONID0161"] =>
string(17) "50350073XN1446019"
["L_AMT0161"] =>
string(6) "8%2e50"
["L_FEEAMT0161"] =>
string(9) "%2d0%2e55"
["L_NETAMT0161"] =>
string(6) "7%2e95"
}
["08591"] =>
array(5)
{
["L_NAME08591"] =>
string(18) "Norbert%20Bendixen"
["L_TRANSACTIONID08591"] =>
string(17) "1WN98871MS4263823"
["L_AMT08591"] =>
string(6) "8%2e50"
["L_FEEAMT08591"] =>
string(9) "%2d0%2e55"
["L_NETAMT08591"] =>
string(6) "7%2e95"
}
}
Here is the code I am using which is not working for me:
foreach ($reb AS $newrebarray)
{
foreach ($newrebarray as $ke => $val)
{
if (preg_match("/L_NETAMT/i", $ke))
{
$newarrayreb1 = array('Net' => $val);
}
if (preg_match("/L_TRANSACTIONID/i", $ke))
{
$newarrayreb1 = array('TransactID' => $val);
}
if (preg_match("/L_NAME/i", $ke))
{
$newarrayreb1 = array('Name' => $val);
}
}
}
notice that the array keys are dynamic, I want to create a new array with static keys, and the associated values. When I run the code, I get five different arrays.
First I would define a function that does replacement based on a captured memory segment of a regular expression:
function do_translate($match)
{
switch ($match[1]) {
case 'L_NAME':
return 'Name';
case 'L_NETAMT':
return 'Net';
case 'L_TRANSACTIONID':
return 'TransactID';
}
// in all other cases, return the full match
return $match[0];
}
Then iterate over the blocks, send the array keys through a translation pass and then recombine the new keys with the existing values:
foreach ($reb as $id => $data) {
$new_keys = preg_replace_callback('/^(L_[A-Z]+)' . preg_quote($id) . '$/i', 'do_translate', array_keys($data));
// create the new array with translated keys
$reb[$id] = array_combine($new_keys, $data);
}
I noticed that the array keys were a combination of the field and the product id (I guess), so I've used that knowledge to strengthen the regular expression
Not tested, haven't fully woken up yet, so this'll probably kick your dog and delete all your savegames:
$translations = array(
'L_TRANSACTIONID' => 'Translation',
'L_NAME' => 'Name',
'L_NETAMT' => 'Net'
);
foreach($array as $parentkey => $subarray) {
foreach($subarray as $subkey => $val) {
if (preg_match('/^(L_.*?)\d*$/', $matches)) {
$newKey = $translations[$matches[1]];
$array[$parentkey][$newkey] = $val;
unset($array[$parentkey][$subkey]);
}
}
}
Related
I have a multi-dimensional array that needs to be "searchable" based on provided keys that may represent multiple levels w/in the array and change that found value.
// array that needs to be searched
$array = [
'one' => [
'two' => [
'three' => 'four',
],
],
'five' => [
'six' => 'eight',
],
];
// array that represent the change
$change = [
'five|six' => 'seven',
];
I need to find $array['five']['six'] dynamically and change that value to the provided. There may be multiple changes and they could be of varying depths. Note: the arrays I am really using are larger and deeper,
Last attempt:
foreach ($change as $k => $v) {
$keyList = '';
$keys = explode('|', $k);
foreach ($keys as $key) {
$keyList .= '[' . $key . ']';
}
$array[$keyList] = $v;
// throws a notice: Notice: Undefined index (realize it is a string representation of keys.
// Tried some other ways but nothing is clicking
}
Any time you need to traverse a data structure of arbitrary depth you're likely going to need recursion. For this you need a function to get an arbitrary path in the data, and another to set it.
function get_path($arr, $path) {
$cur = array_shift($path);
if( empty($path) ) {
return $arr[$cur];
} else {
return get_path($arr[$cur], $path);
}
}
function set_path(&$arr, $path, $value) {
$cur = array_shift($path);
if( empty($path) ) {
$arr[$cur] = $value;
} else {
set_path($arr[$cur], $path, $value);
}
}
foreach ($change as $k => $v) {
$keys = explode('|', $k);
set_path($array, $keys, $v);
}
var_dump($array);
Output:
array(2) {
["one"]=>
array(1) {
["two"]=>
array(1) {
["three"]=>
string(4) "four"
}
}
["five"]=>
array(1) {
["six"]=>
string(5) "seven"
}
}
How can I convert the string test[1][2][3][4][5] to a multidimensional PHP array like:
array(1 => array(2 => array( 3 => array( 4 => array(5 => array()))));
If I understood your question correctly, you're asking to convert the string "test[1][2][3][4][5]" to array(1 => array(2 => array( 3 => array( 4 => array(5 => array()))));
First of all, people usually use the short array() notation, which is just [].
Second, why use strings, when you can just type
$test[1][2][3][4][5] = [];
to get what you want.
If you really want strings, you can do it in several ways, one of which is:
function makeArrayFromString($string, &$name)
{
$namePosEnd = strpos($string, '['); // name ends when first [ starts
if (!$namePosEnd) return false; // didn't find [ or doesn't start with name
$name = substr($string, 0, $namePosEnd);
$dimensionKeys = [];
$result = preg_match_all('/\[([0-9]+)\]/', $string, $dimensionKeys); // get keys
if (!$result) return false; // no matches for dimension keys
$dimensionKeys = array_reverse($dimensionKeys[1]);
$multiArray = [];
foreach ($dimensionKeys as $key)
{
$key = (int)$key; // we have string keys, turn them to integers
$temp = [];
$temp[$key] = $multiArray;
$multiArray = $temp;
}
return $multiArray;
}
$string = 'test[1][2][3][4][5]';
$name = '';
$multiArray = makeArrayFromString($string, $name);
if ($multiArray === false)
exit('Error creating the multidimensional array from string.');
$$name = $multiArray; // assign the array to the variable name stored in $name
var_dump($test); // let's check if it worked!
Outputs:
array(1) {
[1]=>
array(1) {
[2]=>
array(1) {
[3]=>
array(1) {
[4]=>
array(1) {
[5]=>
array(0) {
}
}
}
}
}
}
Keep in mind that I didn't add any checks if the $name string satisfies the PHP variable naming rules. So you might get an error if you do something like 111onetest[1][2][3][4][5], as variable names in PHP can't start with a number.
My "main" array looks like this - var_dump($main)
[zlec_addresoperator] => and
[filtervalue0] => Test
[filtercondition0] => CONTAINS
[filteroperator0] => 1
[filterdatafield0] => zlec_addres
[zlec_nroperator] => and
[filtervalue1] => SecondVal
[filtercondition1] => CONTAINS
[filteroperator1] => 1
[filterdatafield1] => zlec_nr
I want to build a new array as
array( filterdatafield0 = > filtervalue0 , filterdatafield1 = > filtervalue1)
etc
First of all I decided to filter out what I wan't with the following codes. Creating new arrays to keep the data I wan't, so $arraykeys will contain the filterdatafield.{1,2} values. In this case it will be zlec_addres and zlec_nr.
The second $arrayvalue will keep the filtervalue.{1,2} which is the value for the filter.
$newarray = array();
$arraykeys = array();
$arrayvalue = array();
foreach($_GET as $key => $value):
if(preg_match("/^filterdatafield.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arrayvalue[] = $value;
}
if(preg_match("/^filtervalue.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arraykeys[] = $key;
}
endforeach;
foreach($arraykeys as $a){
$newarray[$a] = $arrayvalue;
}
So the desired output would be
array(
zlec_addres => 'Test', zlec_nr = 'SecondVal'
)
Now it is
array(12) {
["filtervalue0"]=>
array(12) {
[0]=>
string(11) "zlec_addres"
[1]=>
string(7) "zlec_nr"
...
}
["filtervalue1"]=>
array(12) {
[0]=>
string(11) "zlec_addres"
[1]=>
string(7) "zlec_nr"
...
}
$newarray = array();
$arraykeys = array();
$arrayvalue = array();
foreach($_GET as $key => $value){
if(preg_match("/^filterdatafield.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arraykeys[] = $value;
}
if(preg_match("/^filtervalue.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arrayvalues[] = $value;
}
}
$newArray = array_combine($arraykeys, $arrayvalues);
This should work for you:
Just grab your keys which you want with preg_grep() and then array_combine() both arrays together.
<?php
$arr = [
"zlec_addresoperator" => "and",
"filtervalue0" => "Test",
"filtercondition0" => "CONTAINS",
"filteroperator0" => "1",
"filterdatafield0" => "zlec_addres",
"zlec_nroperator" => "and",
"filtervalue1" => "SecondVal",
"filtercondition1" => "CONTAINS",
"filteroperator1" => "1",
"filterdatafield1" => "zlec_nr",
];
$newArray = array_combine(
preg_grep("/^filterdatafield\d+$/", array_keys($arr)),
preg_grep("/^filtervalue\d+$/", array_keys($arr))
);
print_r($newArray);
?>
output:
Array
(
[filterdatafield0] => filtervalue0
[filterdatafield1] => filtervalue1
)
To begin with I have an array (courses) like this:
array(2)
{
[0] => array(2)
{
["title"] => string "course1"
["code"] => string "001, 002, 003"
}
[1] => array(2)
{
["title"] => string "course2"
["ps_course_code"] => string "004"
}
}
Sometimes the 'code' will contain multiple codes as a comma separated string, other times 'code' will contain a single code.
To get individual codes I loop through the courses array and use explode to separate out the codes:
foreach($courses as $course) {
$courseInfo['code'] = explode(",",$course["code"]);
$courseInfo['title'] = $course["title"];
var_dump($courseInfo);
}
This gives me a new array for each course:
array(2)
{
["code"] => array(3)
{
[0] => string "001",
[1] => string "002",
[2] => string "003",
}
["title"] => string "course1"
}
array(2)
{
["code"] => array(1)
{
[0] => string "004"
}
["title"] => string "course2"
}
What I need though is a new array that contains every code and its title. So for some courses this means there will be multiple codes with the same title. E.g:
array(4)
{
[0] => array (2)
{
["code"] => string "001",
["title"] => string "course1"
}
[1] => array (2)
{
["code"] => string "002",
["title"] => string "course1"
}
[2] => array (2)
{
["code"] => string "003",
["title"] => string "course1"
}
[3] => array (2)
{
["code"] => string "004",
["title"] => string "course1"
}
}
I'm really struggling with this. Do I need another loop inside the first in order to create the final array?
foreach($courses as $course) {
$courseInfo['code'] = explode(",",$course["code"]);
$courseInfo['title'] = $course["title"];
// Another loop to create final array?
foreach($courseInfo as $value) {
$final['code'] = $value['code']; // I know this doesn't work!
$final['title'] = $value['title'];
}
}
var_dump($final);
I know this is long and I probably haven't explained this very well, so apologies!
You can get the desired output by looping over your first array:
$final = array();
foreach ($courses as $course) {
$codes = array_map('trim', explode(',', $course['code']));
foreach ($codes as $c) {
$final[] = array('code' => $c, 'title' => $course['title']);
}
}
Demo
You'd need to loop around the array of courses, not the full array.
i.e. something like this:
$i = 0;
foreach($courses as $course) {
$codes = explode(",",$course["code"]);
foreach($codes as $code) {
$final[$i]['code'] = $code;
$final[$i]['title'] = $course['title'];
$i++;
}
}
var_dump($final);
Easiest way to create array from the array value code is to loop through the array and explode the values, like you did.
$new_array = array(); //optionally for adding to new array
foreach($courses as $course)
{
$code = explode(',', $course['code']);
$trimmed_code = array_walk($code, function($value)
{
//trim the value to remove spaces before and after value
return trim($value);
});
$course['code'] = $trimmed_code;
//code for optionally add to new array
$new_array[] = array(
'code' => $code,
'title' => $course['title'],
);
}
foreach($courses as $course) {
$codes = explode(",",$course["code"]);
for($i=0;$i<count($codes); $i++){
$courseInfo['code'] = $codes[i];
$courseInfo['title'] = $course["title"];
}
var_dump($courseInfo);
}
I've looked up a bunch of similar examples but still can't seem to figure out how loop through and echo the values from this array. Should be simple, but I'm dense. Help is appreciated.
array(2) { ["legend_size"]=> int(1) ["data"]=> array(2) { ["series"]=> array(2) { [0]=> string(10) "2014-01-17" [1]=> string(10) "2014-01-18" } ["values"]=> array(1) { ["Begin Session"]=> array(2) { ["2014-01-17"]=> int(1073) ["2014-01-18"]=> int(1122) } } } }
I'm trying to return the int values for the "values" array.
Given the name of your array is, for the sake of example, $mdarr, and that the construction of the array is going to be roughly the same every time, it is as simple as:
$values_i_want = $mdarr['data']['values'];
If the values array you are looking for is going to be in different array depths in different cases, recursion combined with type checking will do the trick:
//returns values array or nothing if it's not found
function get_values_array($mdarr) {
foreach ($mdarr as $key => $val) {
if ($key == 'values') {
return $val;
} else if (is_array($val)) {
return get_values_array($val);
}
}
}
Use the following as a base. I reconstructed your array so I could mess around with it.
$turtle = array('legend_size' => 'int(1)', 'data' =>array('series' => array('string(10) "2014-01-17"', '[1]=> string(10) "2014-01-18"'), 'values' => array('Begin_Session' =>array('2014-01-17' => 'int(1073)', '2014-01-18' => 'int(1122)'))));
// This is where you "navigate" the array by using [''] for each new array you'd like to traverse. Not sure that makes much sense, but should be clear from example.
foreach ($turtle['data']['values']['Begin_Session'] as $value) {
$match = array();
// This is if you only want what's in the parentheses.
preg_match('#\((.*?)\)#', $value, $match);
echo $match[1] . "<br>";
}
If the array structure is not going to change, and you just want the int values inside values, you could do the following:
//Create array
$some_array = array(
"legend_size" => 5,
"data" => array(
"series" => array(0 => "2014-01-17", 1 => "2014-01-18" )
"values" => array(
"Begin Session" => array("2014-01-17" => 1000, "2014-01-18" => 1000)
)
)
);
//Get values
foreach($some_array['data']['values'] as $key => $value)
{
if(is_array($value))
{
echo $key . " => ";
foreach($value as $key2 => $value2)
{
echo " " . $key2 . " => " . $value2;
}
}
else
{
echo $key . " => " . $value;
}
}
This will give you an output like this:
Begin Session =>
2014-01-17 => 1000
2014-01-18 => 1000