Using str_replace() to replace values in a couple paragraphs of text data, it seems to do so but in an odd order. The values to be replaced are in a hard-coded array while the replacements are in an array from a query provided by a custom function called DBConnect().
I used print_r() on both to verify that they are correct and they are: both have the same number of entries and are in the same order but the on-screen results are mismatched. I expected this to be straightforward and didn't think it needed any looping for this simple task as str_replace() itself usually handles that but did I miss something?
$replace = array('[MyLocation]','[CustLocation]','[MilesInc]','[ExtraDoc]');
$replacements = DBConnect($sqlPrices,"select",$siteDB);
$PageText = str_replace($replace,$replacements,$PageText);
and $replacements is:
Array
(
[0] => 25
[MyLocation] => 25
[1] => 45
[CustLocation] => 45
[2] => 10
[MilesInc] => 10
[3] => 10
[ExtraDoc] => 10
)
Once I saw what the $replacements array actually looked like, I was able to fix it by filtering out the numeric keys.
$replace = array('[MyLocation]','[CustLocation]','[MilesInc]','[ExtraDoc]');
$replacements = DBConnect($sqlPrices,"select",$siteDB);
foreach ($replacements as $key=>$value) :
if (!is_numeric($key)) $newArray[$key] = $value;
endforeach;
$PageText = str_replace($replace,$newArray,$PageText);
The former $replacements array, filtered to $newArray, looks like this:
Array
(
[MyLocation] => 25
[CustLocation] => 45
[MilesInc] => 10
[ExtraDoc] => 10
)
-- edited: Removed some non sense statements --
#DonP, what you are trying to do is possible.
In my opinion, the strtr() function could be more beneficial to you. All you need to make a few adjustments in your code like this ...
<?php
$replacements = DBConnect($sqlPrices,"select",$siteDB);
$PageText = strtr($PageText, [
'[MyLocation]' => $replacements['MyLocation'],
'[CustLocation]' => $replacements['CustLocation'],
'[MilesInc]' => $replacements['MilesInc'],
'[ExtraDoc]' => $replacements['ExtraDoc'],
]);
?>
This code is kinda verbose and requires writing repetitive strings. Once you understand the way it works, you can use some loops or array functions to refactor it. For example, you could use the following more compact version ...
<?php
// Reference fields.
$fields = ['MyLocation', 'CustLocation', 'MilesInc', 'ExtraDoc'];
// Creating the replacement pairs.
$replacementPairs = [];
foreach($fields as $field){
$replacementPairs["[{$field}]"] = $replacements[$field];
}
// Perform the replacements.
$PageText = strtr($PageText, $replacementPairs);
?>
Related
I have a problem with the array PHP function, below is my first sample code:
$country = array(
"Holland" => "David",
"England" => "Holly"
);
print_r ($country);
This is the result Array ( [Holland] => David [England] => Holly )
I want to ask, is possible to make the array data become variables? For second example like below the sample code, I want to store the data in the variable $data the put inside the array.:
$data = '"Holland" => "David","England" => "Holly"';
$country = array($data);
print_r ($country);
But this result is shown me like this: Array ( [0] => "Holland" => "David","England" => "Holly" )
May I know these two conditions why the results are not the same? Actually, I want the two conditions can get the same results, which is Array ( [Holland] => David [England] => Holly ).
Hope someone can guide me on how to solve this problem. Thanks.
You can use the following Code.
<?php
$country = array(
"Holland" => "David",
"England" => "Holly"
);
foreach ($country as $index => $value)
{
$$index = $value;
}
?>
Now, Holland & England are two variables. You can use them using $Holland etc.
A syntax such as $$variable is called Variable Variable. Actually The inner $ resolves the a variable to a string, and the outer one resolves a variable by that string.
So there is this thing called
Destructuring
You can do it something like ["Holland" => $eolland, "England" => $england] = $country;
And now you have your array elements inside the variables.
Go read the article above if you want more information about this because it gets really useful (especially in unit tests usind data provders from my experience).
If you want to extract elements from an associative array such that the keys become variable names and values become the value of that variable you can use extract
extract($country);
To check what changed you can do
print_r(get_defined_vars());
Explanation on why the below does not work
$data = '"Holland" => "David","England" => "Holly"';
When you enclose the above in single quotes ' php would recognise it as a string. And php will parse a string as a string and not as an array.
Do note it is not enough to create a string with the same syntax as the code and expect php to parse it as code. The codes will work if you do this
$data = ["Holland" => "David","England" => "Holly"];
However, now $data itself is an array.
A simple copy of an array can be made by using
$data = $country;
I am struggling with what would appear to be a pretty straight forward task. I have looked at and tried all kinds of functions and suggestion on SO hoping that maybe there is something simple and functional out there. Nothing I tried gives me the logic to do the restructuring.
I have a long complex array. However very much simplified the logic problem I am trying to solve generically is as follows:
$cost_type = Array
(
0 => "ISP2",
1 => "ISP3",
2 => "ISP4"
);
$supplier_name = Array
(
0 => "NAME-A",
1 => "NAME-B",
2 => "NAME-C"
);
$propertyid = Array
(
0 => "property1",
1 => "property2",
2 => "property2"
);
and I need to convert it to the following set of arrays (noting the concatenation of the two arrays with a common property id.....
$property1
(
array['charges']
[0] =>IPS2
array ['names']
[0] =>NAME-A
)
$property2
(
array['charges']
[0] ->IPS3
[1] =>IPS4
array['names']
[0] =>NAME-B
[1] =>NAME-c
)
I have tried everything over the course of the last few hours and a simple solution totally evades me.
If you can join the three arrays as you say in comments above this code will generate the look you want.
I loop through the array with property and keep key as the key to find names and charges in the other subarrays.
$cost_type = Array
(
0 => "ISP2",
1 => "ISP3",
2 => "ISP4"
);
$supplier_name =Array
(
0 => "NAME-A",
1 => "NAME-B",
2 => "NAME-C"
);
$propertyid = Array
(
0 => "property1",
1 => "property2",
2 => "property2"
);
$arr[] = $cost_type;
$arr[] = $supplier_name;
$arr[] = $propertyid;
$result = array();
Foreach($arr[2] as $key => $prop){
$result[$prop]["charges"][] =$arr[0][$key];
$result[$prop]["names"][] = $arr[1][$key];
}
Var_dump($result);
https://3v4l.org/EilvE
The following code converts the original array in the expected result:
$res = array();
foreach($arr[2] as $k => $foo){ // foreach property
if(!isset($res[$foo])){ // add property if not yet in list
$res[$foo] = array(
'charges' => array($arr[0][$k]),
'names' => array($arr[1][$k])
);
}else{ // add new value to already existing property
$res[$foo]['charges'][] = $arr[0][$k];
$res[$foo]['names'][] = $arr[1][$k];
}
}
Check it out here: https://eval.in/904473
Of course, it assumes a bunch on things about the data, but it should work for any number of items.
And if you need the property in another variable, just access it with $res['name of it].
Run this code you will get smiler result as you want :
$twodimantion=array();
$properties=array('property1','property2','property3');
$charges=array('ISP2','ISP3','ISP4');
$names=array('NAME-A','NAME-B','NAME-C');
foreach ($properties as $key => $property) {
$twodimantion['charge'][$key]=$charges[$key];
$twodimantion['names'][$key]=$names[$key];
$twoarray[$property]=$twodimantion;
}
echo '<pre>';
print_r($twoarray);
echo '</pre>';
I can't say I completely follow what you are trying to do, but I think this may be part of the way there for you.
When trying to restructure data in PHP, it's often helpful to create a empty array (or other data structure) to store the new data in first. Then you find a way to loop over your initial data structure that allows you to insert items into your reformatted structure in the right sequence.
<?php
$properties = []; // Array to hold final result
// Loop over your initial inputs
foreach ($groupsOfValues as $groupName => $groupValues) {
$temp = []; // Array to hold each groupings reformatted data
// Loop over the items in one of the inputs
for ($i=0; $i<count($group) && $i<count($properties)+1; $i++) {
if (!is_array($temp[$groupName])) {
$temp[$groupName] = [];
}
$temp[$groupName][] = $group[$i];
}
$properties[] = $temp;
}
I have the following array, I'm trying to append the following ("","--") code
Array
(
[0] => Array
(
[Name] => Antarctica
)
)
Current JSON output
[{"Name":"Antarctica"}]
Desired output
{"":"--","Name":"Antarctica"}]
I have tried using the following:
$queue = array("Name", "Antarctica");
array_unshift($queue, "", "==");
But its not returning correct value.
Thank you
You can prepend by adding the original array to an array containing the values you wish to prepend
$queue = array("Name" => "Antarctica");
$prepend = array("" => "--");
$queue = $prepend + $queue;
You should be aware though that for values with the same key, the prepended value will overwrite the original value.
The translation of PHP Array to JSON generates a dictionary unless the array has only numeric keys, contiguous, starting from 0.
So in this case you can try with
$queue = array( 0 => array( "Name" => "Antarctica" ) );
$queue[0][""] = "--";
print json_encode($queue);
If you want to reverse the order of the elements (which is not really needed, since dictionaries are associative and unordered - any code relying on their being ordered in some specific way is potentially broken), you can use a sort function on $queue[0], or you can build a different array:
$newqueue = array(array("" => "--"));
$newqueue[0] += $queue[0];
which is equivalent to
$newqueue = array(array_merge(array("" => "--"), $queue[0]));
This last approach can be useful if you need to merge large arrays. The first approach is probably best if you need to only fine tune an array. But I haven't ran any performance tests.
Try this:
$queue = array(array("Name" => "Antarctica")); // Makes it multidimensional
array_unshift($queue, array("" => "--"));
Edit
Oops, just noticed OP wanted a Prepend, not an Append. His syntax was right, but we was missing the array("" => "--") in his unshift.
You can try this :
$queue = array("Name" => "Antarctica");
$result = array_merge(array("" => "=="), $queue);
var_dump(array_merge(array(""=>"--"), $arr));
Currently I'm using foreach to search key when use array_replace:
$grades = array(
0 =>array('id'=>1, 'grade'=>4),
1 =>array('id'=>5, 'grade'=>2),
2 =>array('id'=>17,'grade'=>1),
)
$replacement = array('id'=>17,'grade'=>3);
foreach($grades as $key=>$grade){
if($grade->id ==$replacement['id'] )
$found = $key;
}
$new_grades = array_replace($grades, array($found_key=>$replacement));
I wonder if this will become inefficient when the number of elements grow too much in $grades array. Is there any better way to do the search and replace job?
The execution time grows linearly with the number of elements in the array (O(N)). Use a better data structure, i.e. use the array in an associative way with the ID as index:
$grades = array(
1 => array('grade'=>4),
5 => array('grade'=>2),
17 => array('grade'=>1)
);
Then the lookup cost is constant (O(1)). You can do:
$grades[$replacement['id']] = array('grade' => $replacement['grade']);
or something similar, depending on your data.
Yeah, that can be done vastly more efficiently.
$grades = array(
1 => 4,
5 => 2,
17 => 1,
);
$replacement = array(
17 => 3,
);
$grades = array_merge($grades, $replacement);
If you need more information associated with the ID than just the grade, then you'll still need a more involved data structure like Felix Kling has. But no such requirement is present in your question so I'm not assuming it.
I have a weird phenomenon. I hope someone can explain to me what is happening there:
I want to create a filter. The origin is something like '-10' or '10-20' or '20+' (type string) and the result should be 'Under $10', ... as well as 'product_price < 10', ... for a sql command.
But storing the array back on the original string doesn't work. It just delivers '$Array' as result. Is it not possible to pass by reference and change the type?
Thanks for your knowledge!
foreach($filters as &$filter){
preg_match ('#^\-(\d+)$#ism', $filter, $match);
if ($match[1]){
$filter = array(
'Under $'.intval($match[1]),
'product_price < '.intval($match[1])
);
}
...
}
return $filtering;
}
P.S.: I am not looking for a solution, because I could change the origin string into array, or I could change the foreach in to a pass by value and create a new array with the arrays like $newFilter[] = ... I am only curious
You can change it's type. Proof by construction:
<?php
header('Content-type:text/plain');
$arr = array(
'1',
'2',
);
foreach ($arr as &$filter) {
$filter = array($filter);
}
print_r($arr);
?>
Prints:
Array
(
[0] => Array
(
[0] => 1
)
[1] => Array
(
[0] => 2
)
)
You should change your foreach into
foreach($filters as $index => $filter)
and update your filter by doing
$filters[$index] = array(...);
I believe the $filter variable created by the foreach() statement is a copy of the data in the array and not a reference to it.