PHP: Pass dynamically created variables to a built-in function - php

DESCRIPTION OF PROBLEM:What I am trying to do is pass dynamically created variables from a loop to a function in php. More specifically, I used a for loop to create variables and assign data to them. Then use a for loop to string all the variables together. Then pass the string to the multisort_array function and explode the string to use the variables. I'm not sure what I am doing wrong.
QUESTION:How would I pass a bunch of dynamically created variables to a sort function without knowing how many I am going to create? That is my delema.
CODE:
$arr2[0] = "100::HOMEDEPOT";
$arr2[1] = "200::WALMART";
$arr2[2] = "300::COSTCO";
$arr2[3] = "400::WALGREENS";
$arr2[4] = "500::TACO BELL";
// explodes first value of $arr2
$tmp = explode("::",$arr2[0]);
// determines how many dynamic variables to create
for($k=0;$k<count($tmp);$k++){
${"mArr".$k} = Array();
}
// loops thru & assigns all numbers to mArr0
// loops thru & assigns all names to mArr1
for ($k=0;$k<count($arr2);$k++){
$tmp = explode("::",$arr2[$k]);
for($l=0;$l<count($tmp);$l++){
${"mArr".$l}[$k] = $tmp[$l];
}
}
// Will add a for loop to combine the variables into string
$param = "$mArr1,$mArr0";
// send the string to array_multisort to be sorted by name
// have tried the following options:
// 1. array_multisort(explode(",",$param));
// 2. call_user_func_array(array_multisort,explode(",",$param));
// both do not sort & give me an error.
Thank you in advance for your help. I am open to any suggestions on other ways this can be accomplished, but I would like it to be in the php code if at all possible.

Just pass the array itself into the function.
arraySort($array);

Sort the array before splitting it in to other arrays using a custom sorting function:
$arr2[0] = "100::HOMEDEPOT";
$arr2[1] = "200::WALMART";
$arr2[2] = "300::COSTCO";
$arr2[3] = "400::WALGREENS";
$arr2[4] = "500::TACO BELL";
//Split the input in place, you could also use a new array for this
for($i = 0;$i < count($arr2);$i++)
{
$arr2[$i] = explode("::",$arr2[$i]);
}
//Define our new sorting function
function sort_second_item($a,$b)
{
return strcmp($a[1],$b[1]);
}
var_dump($arr2);
usort($arr2,'sort_second_item');
var_dump($arr2);
$rotated = array();
//Rotate $arr2
for($i = 0; $i < count($arr2); $i++)
{
for($j = 0;$j < count($arr2[$i]); $j++)
{
if(!isset($rotated[$j]))
{
$rotated[$j] = array();
}
$rotated[$j][$i] = $arr2[$i][$j];
}
}
var_dump($rotated);

Related

How to create empty string using for loop PHP

I'm trying to create for loop giving strings empty value. How I can do it?
for ($i = 1; $i <= 24; $i++) {
$b2_ch_v = ${'b2_g_v_'.$i}['id'];
$$b2_ch_v = '';
}
/*
result should be:
$b2_g_v_1['id'] = '';
$b2_g_v_2['id'] = '';
[...]
$b2_g_v_24['id'] = '';
*/
Don't use variables named like $x1, $x2, $x3. You almost always want to use arrays instead. In this case, you can use an indexed array of associative arrays. This is sometimes also called a two-dimensional array.
for ($i = 0; $i < 24; $i++) {
$b2_ch_v[$i] = ['id' => ''];
}
Then your first element becomes:
$b2_ch_v[0]
And its named elements can be referred to via:
$b2_ch_v[0]['id']
You're setting $b2_ch_v to the current contents of the id element of the array, not a reference to the array element. You need to refer to the array index in the assignment.
for ($i = 1; $i <= 24; $i++) {
$b2_ch_v = 'b2_g_v_'.$i;
${$b2_ch_v}['id'] = '';
}
var_dump($b2_g_v_1); // => array(1) { ["id"]=> string(0) "" }
You don't actually need the variable, you can do the calculation in the assignment:
${'b2_g_v_'.$i}['id'] = '';
But it's best to avoid variable variables in the first place, and use arrays instead as in the other answer.

PHP - Stop need to create hundreds of variables

I'm writing a script and it seems like a bit of a ballache so I came on SO to ask for a little help making my script more dynamic so I create a better version of what I'm doing. I've read into variable variables but I'm still stuck on how I'd use them.
I'll obviously shorten this down but my current script is:
$a0 = $tags['items'][0]['snippet']['tags'];
$a1 = $tags['items'][1]['snippet']['tags'];
$a2 = $tags['items'][2]['snippet']['tags'];
if (!is_array($a0)) { $a0 = array(); }
if (!is_array($a1)) { $a1 = array(); }
if (!is_array($a2)) { $a2 = array(); }
$a0 = array_map('strtolower', $a0);
$a1 = array_map('strtolower', $a1);
$a2 = array_map('strtolower', $a2);
array_count_values(array_merge($a0,$a1,$a2));
I'm looking for a way to dynamically create the variables (For example using an index in a while loop rather than creating these variables uniquely. This obviously is fine on a small scale, but i've currently done 50 of these for each and it's causing serious time problems. Any help is much appreciated
Treat the whole $tags variable as an array and you can do this, similar to the strtolower array_map you have already:
$tagItems = [];
foreach($tags['items'] as $item) {
if (!$item['snippet']['tags'] || !is_array($item['snippet']['tags'])) {
continue;
}
foreach($item['snippet']['tags'] as $tag) {
$tag = strtolower($tag);
if (!isset($tagItems[$tag])) {
$tagItems[$tag] = 0;
}
$tagItems[$tag]++;
}
}
As #FranzGleichmann says, try not to use variable variables, which are a smell and potential security risk, but instead rethink how you want to approach the problem.
You should be able to produce the same output that you get from array_count_values with a nested foreach loop.
foreach ($tags['items'] as $x) { // loop over the list of items
foreach ($x['snippet']['tags'] as $tag) { // loop over the tags from each item
$tag = strtolower($tag);
if (!isset($counts[$tag])) $counts[$tag] = 0;
$counts[$tag]++; // increment the tag count
}
}
No need to create 100 variables. That would cause a headache. Instead, use a simple loop function.
$b = array();
for ($n=1; $n<=100; $n++) {
$a = $tags['items']["$n"]['snippet']['tags'];
if (!is_array($a)) { $a = array(); }
$a = array_map('strtolower', $a);
array_count_values(array_merge($b,$a));
}
I hope it works! Have a nice coding
I would write this in a comment but i will a long one,
Variable Variable, is simply the value of the original var assigned as a var name, which means:
$my_1st_var = 'im_1st';
//use $$
$$my_1st_var = 'im_2nd'; //that is the same of $im_1st='im_2nd';
//results
echo $my_1st_var; // >>> im_1st
echo $im_1st; // >>> im_2nd
that means i created a new var and called it the value of the 1st var which is im_1st and that makes the variable name is $im_1st
also you can set multiple values as a var name:
$var0 = 'a';
$var1 = 'b';
$var2 = 'c';
$var3 = '3';
//we can do this
${$var0.$var1} = 'new var 1'; //same as: $ab = 'new var 1';
${$var1.$var2.$var3} = 'im the newest'; //same as: $bc3 = 'im the newest';
//set a var value + text
${$var0.'4'.$var1} = 'new?'; //same as: $a4b = 'new?';
also $GOLBALS[]; is some kind of $$
hope it helps you understanding what is hard for you about $$ ;)
Alright so dynamically creating variables is easy is a script language like PHP.
You could make $a an array, and instead of $a0, $a1, ... use $a[$i] where $i goes from 0 to 50 or more.
Or you could use this nice funky syntax: ${'a'.$i}. For example:
$i = 0;
${'a'.$i} = 'foobar';
echo $a0; // will output foobar
However you shouldn't do any of this.
What you should do is think about what you are trying to achieve and come up with a different algorithm that doesn't require dynamically named variables.
In this case, something like this looks like it would do the job:
$result = [];
foreach ( $tags['items'] as $item ) {
if ( is_array($item['snippet']['tags']) ) {
$result = array_merge($result, array_map('strtolower',$item));
}
}
array_count_values($result);
This is obviously not tested and from the top of my head, but I hope you get the idea. (EDIT: or check the other answers with similarly rewritten algorithms)

Explode and then merge arrays

I have two strings, one containing names separated by commas and the other containing email addresses separated by commas.
I now want my end result to replicate the behaviour as if I had gotten those values from the database with a:
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
echo $row['name'].'<br />'.$row['email'];
}
So I have for example these strings:
email1#domain.com,email2#domain.com,email3#domain.com
and
name1,name2,name3
And can then explode these into value arrays. Now, after exploding them,
I want to be able to make a loop where in each loop I can get $name[0] and $email[0] together, and $name[1] and $email[1] together, etc.
How can I merge the two arrays (after exploding them) and get the data for each datapair (name and email) in a loop?
So if I understood you right, you are converting your strings (lets call them email, and name) too two arrays (lets call them arrEmail, and arrName) and now you want to get a array with the merged datasets.(creating the arrays should be easy if not check this out: manual for php explode function)
If so I would create a for loop based on the length of your two arrays. In the loop I would extract value i of arrEmail and arrName, and put the information into an two-dimensional array. Maybe something like this:
It should work but I didn't test it for ages so if not leave me a comment.
<?php
$arrEmail = array();
$arrName = array();
$arrGoal;
$arrLength = count($arrName);
//creating two-dimensional Array
for($i = 0; $i < $arrLength; $i++){
$arrGoal[$i] = array($arrName[$i], $arrEmail[$i]);
//should look something like this ((name, email),(name, email)…)
}
$arrGoalLength = count($arrGoal);
//accessing Array
//1. dimension
for($i = 0; $i < $arrGoalLength; $i++){
//2. dimension
//Variables should be global (but aren't)
$newName = $arrGoal[$i][0];
$newEmail = $arrGoal[$i][1];
}
?>
I think you want something like this:
$output = array();
for ($i = 0; $i < count($names); $i++) {
$output[] = $names[$i] . ' ' . $emails[$i];
}
print_R($output);
$emails = 'email1#domain.com,email2#domain.com,email3#domain.com';
$emails = explode(',', $emails);
$names = 'name1,name2,name3';
$names = explode(',', $names);
and you can use array_combine() as follow :
$combined = array_combine($names, $emails);
foreach($combined as $name => $email){
echo $name, ' : ', $email, '<br/>';
}
I think you should use the built in explode function wich will allow you to turn a string to an array by spliting it using a delimiter (comma) :
$names = explode(",",$row['name']);
$email = explode(",",$row['email']);
for merging them you should use something like this
$Array = array();
for ($j = 0; $j < count($names); $j++) {
$Array[] = [$names[$j],$email[$j]];
}
This is kind a related with your question, but only if you like to access the value by a key(e.g. access the name by email provided):
<?php
$emails = 'email1#gmail.com,email2#gmail.com,email3#gmail.com';
$names = 'name1,name2,name3';
$arrayEmails = explode(',',$emails);
$arrayNames = explode(',',$names);
$result = array_combine( $arrayEmails, $arrayNames);
print_r($result);
?>

Remove a value from an Array in a for loop and replace the previous array with the edited array

i want to eliminate the values from inside the array that has also exist outside the array to form a new array and iterate through the new array to return the first free alphanumeric.
i tried a for loop but it aint working
this is my code
$economyseat = array("5A","5B","5C","5D","5E","5F","6A","6B","6C","6D","6E","6F","7A","7B","7C","7D","7E","7F","8A","8B","8C","8D","8E","8F","9A","9B","9C","9D","9E","9F","10A","10B","10C","10D","10E","10F","11A","11B","11C","11D","11E","11F","12A","12B","12C","12D","12E","12F","13A","13B","13C","13D","13E","13F","14A","14B","14C","14D","14E","14F","15A","15B","15C","15D","15E","15F","16A","16B","16C","16D","16E","16F","17A","17B","17C","17D","17E","17F","18A","18B","18C","18D","18E","18F");
// $seatnumber = 5A,5B,16C & 18A;
$seatlength = count($economyseat);
for ($x = 0; $x < $seatlength; $x++)
{
$seat = $economyseat[$x];
if ($seatnumber == $seat)
{
unset($economyseat[$x]);
//$economyseat = array_remove_by_value($economyseat, $seat);
}
}
Assuming $seatnumber is another array, how about this...
$economyseat = array_diff($economyseat, $seatnumber);
Demo ~ https://eval.in/203332

How to sort it better?

I have 2 arrays, both are multidimensional with same number of elements and same values, which are on different positions (those values are actually ID-s from my database, so one ID appears only once). How can I sort second array with values which are in first array?
For example - if first array looks like:
$array1[0][0] = 1;
$array1[0][x] = it doesn't matter what's here
$array1[1][0] = 4;
$array1[1][x] = it doesn't matter what's here
$array1[2][0] = 3;
$array1[2][x] = it doesn't matter what's here
...
how to sort second array so it would have same values as array1 on indexes [0][0], [1][0], [2][0], etc.
How I could solve problem is:
$i=0
while ($i < (count($array1)-2)){ // * check down
$find_id = $array1[$i][0];
// here I need to search for index of that ID in other array
$position = give_index($find_id, $array2);
// swapping positions
$temp = array2[$i][0];
$array2[$i][0] = $array2[$position][0];
$array2[$position][0] = $temp;
// increasing counter
i++;
}
function give_index($needle, $haystack){
for ($j = 0, $l = count($haystack); $j < $l; ++$j) {
if (in_array($needle, $haystack[$j][0])) return $j;
}
return false;
}
*There is only -2 because indexes start from 0 and also for the last element you don't need to check since it would be automatically sorted by last iteration of while-loop.
I don't find this solution good as I think that this is quite simple issue (maybe it's not even correct). Is there easier way in PHP that I'm missing?
This is the most efficient way I can think of:
function swap(&$a, &$b) {
$t = $a;
$a = $b;
$b = $t;
}
function find_index($id, $array, $from = 0) {
$index = false;
for ($i = $from, $c = count($array); $i < $c; $i++) {
if ($array[$i][0] == $id) {
$index = $i;
break;
}
}
return $index;
}
for ($i = 0, $c = count($array1); $i < ($c - 2); $i++) {
if ($array1[$i][0] != $array2[$i][0]) {
$fi = find_index($array1[$i][0], $array2, $i);
swap($array2[$i][0], $array2[$fi][0]);
}
}
What changes from yours?
I've defined a swap() function in order to swap any variable. That doesn't cost anything and makes everything look nicer. Also you can reuse that function later if you need to.
In the find_index (give_index in your code) we stop the loop once we find the correct index. Also we avoid the cost of an in_array function call.
We modified the find_index function to start only from the part of the array we haven't checked yet. Leading to a way more efficient way of scan the array.
In the for loop (a while loop was just wrong there) we stored the count of the array once, avoiding multiple calls.
Also we swap the $array2 values only if they are in the wrong place.
Other improvements
If you know anything else of the $array2 array you can make this even more performant. For example if you know that indexes are alternated like in $array1 you can change the main for loop from:
for ($i = 0, $c = count($array1); $i < ($c - 2); $i++) {
to
for ($i = 0, $c = count($array1); $i < ($c - 2); $i+2) {
(notice the $i+2 at the end) And you could do that in the find_index function as well.
Look into usort (http://php.net/manual/en/function.usort.php).
It provides a simple way to sort arrays using a user provided comparison function.

Categories