I have an array of strings in PHP like this:
people = array("John","Kim");
I want to convert each of those strings into arrays themselves. Basically, I now want a 2-dimensional array like
people(John[],Kim[]);
I've been struggling with the implementation and am not sure how to do it.
$people = array_fill_keys(array("John","Kim"), array());
Based on your comment, you should be using a combination of keys or values if you want to do this with multi dimensional arrays (which I'm not sure is the best way, but can't say w/o further context).
$people = array(
"john" => array()
);
Then when you want to add products, just go like:
$people["john"]["couch"] = 3; // bought 3 times.
$people["john"][$item] = 0; // if you don't know the count yet for whatever reason. You can always chagne it later the same way.
Now:
foreach( $people as $person => $purchases ){
echo UCFirst( $person );
if( ! empty( $purchases ) ){
echo ' has bought:<br />';
foreach( $purchases as $item => $qty ){
echo $item.' ('.$qty.')<br />';
}
}
}
I would recommend always making your keys either uppercase or lowercase if you are going to use named. Your call though.
If you give us more code / context, there may be much better ways to do this stuff.
Related
i have an array containing several ids sent by GET method, and i want to get each id by a variable , my code was fixed for 2 ids only and i retrieved them using the following code :
$searchString = ',';
if( strpos($_GET['id'], $searchString) != false )
{
$claimID = explode( ',', $_GET['id'] );
$claimID1=$claimID[0];
$claimID2=$claimID[1];
}
Now after a change, is it possible to get more than 2 ids, unlimited, and i want to retrieve them all and use them in queries and layouts, how could i achieve this ? i have to use a loop when exploding and whenever i want to do an operation on all the ids ( query for each id ) i have to loop ?
Ok so i used to explode on , and get the 2 values in 2 different parameters and do 2 queries to get amounts and add them together into 1 amount, and then use an update query for each id, my objective is still the same but for 2+ ids, note that in User No. it takes the 3 values sent but concatinated by commas for now
You can actually dynamically name variables, altough its not recommended:
$arr = [1, 2, 5];
$i = 1;
foreach($arr as $val) {
$name = "claimID" . $i++;
$$name = $val;
}
// Outputs 5
echo $claimID3;
You can create variable variables in PHP but I would not use and do that. Keeping everything in an array is much more easier.
Infos on variable variables: http://php.net/manual/en/language.variables.variable.php
(This is untested and as I said, I wouldn't do it).
if( strpos($_GET['id'], $searchString) != false ) {
$claimID = explode( ',', $_GET['id'] );
for($i=0;$i<count($claimID);$i++) {
$varname = 'claimID' . $i;
$$varname = $claimID[$i];
}
}
So, I have this form that is rather complicated, and the form fields are named to comply with PHP array notation, as such:
<input name='service[123][info]' value=''>
And this of course works as intended and I get the array in $_POST, which I sanitize and then keep in $in. But now I want to reverse-engineer this, when I am iterating over the form again, I have this in $in:
array(
123 => array(
"info" => "foo"
)
)
And when I come to any given form field, I know that the field name is "service[123][info]" but how do I find "foo" in the sent array? Basically, I want to set the value="" parameter in the input when I have data for this field, and the data is kept in the $in array but the only reference to the data I have is the string "service[123][info]". Should I use regexp to parse that string? Sounds inflexible.
Basically, I would like something like:
$name = "service[123][info]";
$value = form_array_lookup($name, $in);
That sets $value to the correct value from $in as referenced by $name. I hope I am making myself clear. Thanks for any comment.
This is a very case-specific (and therefore, not very desirable) example, but the general idea is to use only one delimiter between items, explode the string, and then loop through the result, checking if each item index exists.
function parse_array_path( $string,array $subject ){
// remove ending brackets
$string = str_replace( "]","",$string );
// "[" is now the sole delimiter
$part = explode( "[",$string );
// loop and check for each index in subject array
$i = reset( $part );
do{
if( ! isset( $subject[$i] ) ){
return null;
}
$subject = $subject[$i];
}
while( $i = next( $part ) );
return $subject;
}
example usage:
<?php
$a = array(
"service"=>array(
123=>array(
"info"=>"hello, world"
)
)
);
$s = "service[123][info]";
print parse_array_path( $s,$a ); // "hello, world"
Use a 'foreach' to loop through the array and you can reassign the keys or values in any order you wish.
foreach ($in AS $in_key => $in_val) {
foreach ($in_val AS $in_val_key => $in_val_val) {
// ASSIGN VALUES TO A NEW ARRAY IF YOU WISH
// YOU NOW HAVE $in_key, $in_val_key, $in_val_val
// THAT YOU CAN WORK WITH AND ASSIGN
$array[$in_val_val] = $in_val_key; // OR WHATEVER
}
}
I have an array structured like this:
$arrNames = array(
array('first'=>'John', 'last'=>'Smith', 'id'=>'1'),
array('first'=>'John', 'last'=>'Smith', 'id'=>'2'),
array('first'=>'John', 'last'=>'Smith', 'id'=>'3')
)
I need to remove the similar elements where the fist and last name are the same. Normally, I would use array_unique but the elements aren't exactly unique since each one has a unique id. I do not care which id is retained. I just need the array to look like this:
$arrNames = array(
array('first'=>'John', 'last'=>'Smith', 'id'=>'1') // can be any id from the original array
)
Is there a quick way to accomplish this? My first thought is to use something like a bubble sort but I'm wondering if there is a better (faster) way. The resulting array is being added to a drop-down list box and the duplicate entries is confusing some users. I'm using the ID to pull the record back from the DB after it is selected. Therefore, it must be included in the array.
<?php
$arrNames = array(
array('first'=>'John', 'last'=>'Smith', id=>'1'),
array('first'=>'John', 'last'=>'Smith', id=>'2'),
array('first'=>'John', 'last'=>'Smith', id=>'3')
);
$arrFound = array();
foreach ($arrNames as $intKey => $arrPerson) {
$arrPersonNoId = array(
'first' => $arrPerson['first'],
'last' => $arrPerson['last']
);
if (in_array($arrPersonNoId, $arrFound)) {
unset($arrNames[$intKey]);
} else {
$arrFound[] = $arrPersonNoId;
}
}
unset($arrFound, $intKey, $arrPerson, $arrPersonNoId);
print_r($arrNames);
This definitely works, whether it is the best way is up for debate...
Codepad
There is no fast and easy way that I know of, but here is a relatively simple way of doing it assuming that the ids for "similar elements" don't matter (i.e. you just need an ID period).
$final = array();
foreach ($array as $values) {
$final[$values['first'] . $values['last']] = $values;
}
$array = array_values($final);
The last step is not strictly necessary .. only if you want to remove the derived keys.
I have always sucked at complex arrays there must be something in my brain preventing me from ever understanding them. I will try to make this example really simple so we will not go off topic. I use this code to use numbers to represent each file name:
$mod_nums = array('1' => $input_zip_path . '01_mod_1.0.2.zip',
'2' => $input_zip_path . '02_mod_1.0.1.zip',
);
So when I use $mod_nums['01'] it will display the path to that file. I have an array from the script that put these $mod_nums values into an array like so:
$files_to_zip = array(
$mod_nums['1'],
$mod_nums['2']
);
That worked fine. Now I wanted to add a $_POST value so that I can enter numbers like 1,2 and other numbers that I add to the $mod_nums array later like 1,3,6,12 for example. So I used an explode for those posted values:
$explode_mods = explode(",", trim($_POST['mods']));
Now for the big question that is racking my brain and spent hours on and cannot get it to work.... I need for $files_to_zip to still be in an array and display the posted values of $mod_nums. So it would be like:
$files_to_zip = array( HAVE $_POSTED VALUES IN HERE );
I hope that makes sense. I need $files_to_zip to remain in array format, grab the file path to the zip files from the $mod_nums array, and display it all correctly so it would dynamically output:
$files_to_zip = array('01_mod_1.0.2.zip', '02_mod_1.0.1.zip');
so posted numbers will appear in an array format for the $files_to_zip variable. Make sense? In short I need an array to have dynamic values. Thanks :)
EDIT
Phew I figured it out myself from memory when I worked on something similar many years ago. This looks tough but it isn't. I had to use a foreach and assign the variable into an array like so:
$blah = array();
foreach ($explode_mods as $value)
{
$blah[] = $mod_nums[$value];
}
then I just assigned $files_to_zip to $blah:
$files_to_zip = $blah;
works perfectly :) I just forgot how to dynamically assign values into an array.
// filenames array
$mod_nums = array('1' => $input_zip_path . '01_mod_1.0.2.zip',
'2' => $input_zip_path . '02_mod_1.0.1.zip',
);
// mod_num keys
$explode_mods = explode(',', trim($_POST['mods']));
// array to hold filenames
$files_to_zip = array();
// loop over all the mod_num keys submitted via POST
foreach($explode_mods as $key){
// save the filename to the corresponding array
$files_to_zip[] = $mod_nums[$key];
}
maybe i havn't understood you right, but won't this just be a simple foreach-loop to add the entrys to $files_to_zip like this:
$explode_mods = explode(",", trim($_POST['mods']));
foreach($explode_mods as $k){
$files_to_zip[] = $mod_nums[$k];
}
This is the set of result from my database
print_r($plan);
Array
(
[0] => Array
(
[id] => 2
[subscr_unit] => D
[subscr_period] =>
[subscr_fee] =>
)
[1] => Array
(
[id] => 3
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 90,1000
)
[2] => Array
(
[id] => 32
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 150,1500
)
)
How can I change the $plan[0] to $plan[value_of_id]
Thank You.
This won't do it in-place, but:
$new_plan = array();
foreach ($plan as $item)
{
$new_plan[$item['id']] = $item;
}
This may be a bit late but I've been looking for a solution to the same problem. But since all of the other answers involve loops and are too complicated imho, I've been trying some stuff myself.
The outcome
$items = array_combine(array_column($items, 'id'), $items);
It's as simple as that.
You could also use array_reduce which is generally used for, well, reducing an array. That said it can be used to achieve an array format like you want by simple returning the same items as in the input array but with the required keys.
// Note: Uses anonymous function syntax only available as of PHP 5.3.0
// Could use create_function() or callback to a named function
$plan = array_reduce($plan, function($reduced, $current) {
$reduced[$current['id']] = $current;
return $reduced;
});
Note however, if the paragraph above did not make it clear, this approach is overkill for your individual requirements as outlined in the question. It might prove useful however to readers looking to do a little more with the array than simply changing the keys.
Seeing the code you used to assemble $plan would be helpful, but I'm going assume it was something like this
while ($line = $RES->fetch_assoc()) {
$plan[] = $line;
}
You can simply assign an explicit value while pulling the data from your database, like this:
while ($line = $RES->fetch_assoc()) {
$plan[$line['id']] = $line;
}
This is assuming $RES is the result set from your database query.
In my opinion, there is no simpler or more expressive technique than array_column() with a null second parameter. The null parameter informs the function to retain all elements in each subarray, the new 1st level keys are derived from the column nominated in the third parameter of array_column().
Code: (Demo)
$plan = array_column($plan, null, 'id');
Note: this technique is also commonly used to ensure that all subarrays contain a unique value within the parent array. This occurs because arrays may not contain duplicate keys on the same level. Consequently, if a duplicate value occurs while using array_column(), then previous subarrays will be overwritten by each subsequent occurrence of the same value to be used as the new key.
Demonstration of "data loss" due to new key collision.
$plans = array();
foreach($plan as $item)
{
$plans[$item['id']] = $item;
}
$plans contains the associative array.
This is just a simple solution.
$newplan = array();
foreach($plan as $value) {
$id = $value["id"];
unset($value["id"]);
$newplan[$id] = $value;
}