PHP to Python Code Differences - Arrays, Foreach Loops - php

I hope this question is phrased appropriately to the policies of this site.
I am trying to convert a piece of Python Code to PHP code. I have gotten almost every function translated except I cannot figure out how Arrays and Foreach loops are different in PHP vs Python.
qstid = dbinputsurveyid+'X'+str(question.gid)+'X'+str(question.qid)
index=columns.index(qstid)
for i,a in enumerate(data[index]):
if a!=None and a!='':
answer=int(data[index][i])
answerCodes=list(answersCode[question.qid])
answerindex = answerCodes.index(str(answer))
answerorder = answersOrder[question.qid][a]
addAnswers(db, data[0][i], question.sid, question.gid, question.qid, question.type, answers[question.qid][answerindex], None,answerorder, None, None,None)
From some of the reading I have done. I think enumerate in python is the equivalent to a foreach loop in PHP. But im not sure how "i" and "a" come into play in the code above. They dont seem to be defined like you would in PHP. Any help or insight is appreciated.

The notation i, a in that loop gives you access to the index and values of the list.
From the Python docs:
When looping through a sequence, the position index and corresponding
value can be retrieved at the same time using the enumerate()
function.
So, in Python you'd have:
for i,a in enumerate( ['some', 'list'])
Which would be equivalent to PHP:
$array = ['some', 'array'];
// Or, for PHP < 5.4: $array = array( 'some', 'array');
foreach( $array as $i => $a)

Related

PHP saving a value of array outside of foreach [duplicate]

This question already has answers here:
How to modify an array's values by a foreach loop?
(2 answers)
Closed 4 months ago.
I was wondering if it is possible to edit the current object that's being handled within a foreach loop
I'm working with an array of objects $questions and I want to go through and look for the answers associated with that question object in my db. So for each question go fetch the answer objects and update the current $question inside my foreach loop so I can output/process elsewhere.
foreach($questions as $question){
$question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
There are 2 ways of doing this
foreach($questions as $key => $question){
$questions[$key]['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
This way you save the key, so you can update it again in the main $questions variable
or
foreach($questions as &$question){
Adding the & will keep the $questions updated. But I would say the first one is recommended even though this is shorter (see comment by Paystey)
Per the PHP foreach documentation:
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
Surely using array_map and if using a container implementing ArrayAccess to derive objects is just a smarter, semantic way to go about this?
Array map semantics are similar across most languages and implementations that I've seen. It's designed to return a modified array based upon input array element (high level ignoring language compile/runtime type preference); a loop is meant to perform more logic.
For retrieving objects by ID / PK, depending upon if you are using SQL or not (it seems suggested), I'd use a filter to ensure I get an array of valid PK's, then implode with comma and place into an SQL IN() clause to return the result-set. It makes one call instead of several via SQL, optimising a bit of the call->wait cycle. Most importantly my code would read well to someone from any language with a degree of competence and we don't run into mutability problems.
<?php
$arr = [0,1,2,3,4];
$arr2 = array_map(function($value) { return is_int($value) ? $value*2 : $value; }, $arr);
var_dump($arr);
var_dump($arr2);
vs
<?php
$arr = [0,1,2,3,4];
foreach($arr as $i => $item) {
$arr[$i] = is_int($item) ? $item * 2 : $item;
}
var_dump($arr);
If you know what you are doing will never have mutability problems (bearing in mind if you intend upon overwriting $arr you could always $arr = array_map and be explicit.

php change specific value of nested array item [duplicate]

This question already has answers here:
How to modify an array's values by a foreach loop?
(2 answers)
Closed 4 months ago.
I was wondering if it is possible to edit the current object that's being handled within a foreach loop
I'm working with an array of objects $questions and I want to go through and look for the answers associated with that question object in my db. So for each question go fetch the answer objects and update the current $question inside my foreach loop so I can output/process elsewhere.
foreach($questions as $question){
$question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
There are 2 ways of doing this
foreach($questions as $key => $question){
$questions[$key]['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
This way you save the key, so you can update it again in the main $questions variable
or
foreach($questions as &$question){
Adding the & will keep the $questions updated. But I would say the first one is recommended even though this is shorter (see comment by Paystey)
Per the PHP foreach documentation:
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
Surely using array_map and if using a container implementing ArrayAccess to derive objects is just a smarter, semantic way to go about this?
Array map semantics are similar across most languages and implementations that I've seen. It's designed to return a modified array based upon input array element (high level ignoring language compile/runtime type preference); a loop is meant to perform more logic.
For retrieving objects by ID / PK, depending upon if you are using SQL or not (it seems suggested), I'd use a filter to ensure I get an array of valid PK's, then implode with comma and place into an SQL IN() clause to return the result-set. It makes one call instead of several via SQL, optimising a bit of the call->wait cycle. Most importantly my code would read well to someone from any language with a degree of competence and we don't run into mutability problems.
<?php
$arr = [0,1,2,3,4];
$arr2 = array_map(function($value) { return is_int($value) ? $value*2 : $value; }, $arr);
var_dump($arr);
var_dump($arr2);
vs
<?php
$arr = [0,1,2,3,4];
foreach($arr as $i => $item) {
$arr[$i] = is_int($item) ? $item * 2 : $item;
}
var_dump($arr);
If you know what you are doing will never have mutability problems (bearing in mind if you intend upon overwriting $arr you could always $arr = array_map and be explicit.

ARRAY. Is there a difference between $variable=[]; and $variable = array(); [duplicate]

In certain other languages (AS3 for example), it has been noted that initializing a new array is faster if done like this var foo = [] rather than var foo = new Array() for reasons of object creation and instantiation. I wonder whether there are any equivalences in PHP?
class Foo {
private $arr = array(); // is there another / better way?
}
$myArray = [];
Creates empty array.
You can push values onto the array later, like so:
$myArray[] = "tree";
$myArray[] = "house";
$myArray[] = "dog";
At this point, $myArray contains "tree", "house" and "dog". Each of the above commands appends to the array, preserving the items that were already there.
Having come from other languages, this way of appending to an array seemed strange to me. I expected to have to do something like $myArray += "dog" or something... or maybe an "add()" method like Visual Basic collections have. But this direct append syntax certainly is short and convenient.
You actually have to use the unset() function to remove items:
unset($myArray[1]);
... would remove "house" from the array (arrays are zero-based).
unset($myArray);
... would destroy the entire array.
To be clear, the empty square brackets syntax for appending to an array is simply a way of telling PHP to assign the indexes to each value automatically, rather than YOU assigning the indexes. Under the covers, PHP is actually doing this:
$myArray[0] = "tree";
$myArray[1] = "house";
$myArray[2] = "dog";
You can assign indexes yourself if you want, and you can use any numbers you want. You can also assign index numbers to some items and not others. If you do that, PHP will fill in the missing index numbers, incrementing from the largest index number assigned as it goes.
So if you do this:
$myArray[10] = "tree";
$myArray[20] = "house";
$myArray[] = "dog";
... the item "dog" will be given an index number of 21. PHP does not do intelligent pattern matching for incremental index assignment, so it won't know that you might have wanted it to assign an index of 30 to "dog". You can use other functions to specify the increment pattern for an array. I won't go into that here, but its all in the PHP docs.
In ECMAScript implementations (for instance, ActionScript or JavaScript), Array() is a constructor function and [] is part of the array literal grammar. Both are optimized and executed in completely different ways, with the literal grammar not being dogged by the overhead of calling a function.
PHP, on the other hand, has language constructs that may look like functions but aren't treated as such. Even with PHP 5.4, which supports [] as an alternative, there is no difference in overhead because, as far as the compiler/parser is concerned, they are completely synonymous.
// Before 5.4, you could only write
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// As of PHP 5.4, the following is synonymous with the above
$array = [
"foo" => "bar",
"bar" => "foo",
];
If you need to support older versions of PHP, use the former syntax. There's also an argument for readability but, being a long-time JS developer, the latter seems rather natural to me.  I actually made the mistake of trying to initialise arrays using [] when I was first learning PHP.
This change to the language was originally proposed and rejected due to a majority vote against by core developers with the following reason:
This patch will not be accepted because slight majority of the core developers voted against. Though if you take a accumulated mean between core developers and userland votes seems to show the opposite it would be irresponsible to submit a patch witch is not supported or maintained in the long run.
However, it appears there was a change of heart leading up to 5.4, perhaps influenced by the implementations of support for popular databases like MongoDB (which use ECMAScript syntax).
Prior to PHP 5.4:
$myArray = array();
PHP 5.4 and higher
$myArray = [];
In PHP an array is an array; there is no primitive vs. object consideration, so there is no comparable optimization to be had.
What you're doing is 100% correct.
In terms of nice naming it's often done that private/protected properties are preceded with an underscore to make it obvious that they're not public. E.g. private $_arr = array() or public $arr = array()
Initializing a simple array :
<?php $array1=array(10,20,30,40,50); ?>
Initializing array within array :
<?php $array2=array(6,"santosh","rahul",array("x","y","z")); ?>
Source : Sorce for the code
There is no other way, so this is the best.
Edit: This answer is not valid since PHP 5.4 and higher.
Try this:
$arr = (array) null;
var_dump($arr);
// will print
// array(0) { }
Do not do this:
$arrTst = array( 'IdxKeyOne' => null, 'IdxKeyTwo' => null, 'IdxKeyThr' => null );
There's no such thing as "initializing" an array's index-keys with dummy/placeholder values. print_r gives:
Array (
[IdxKeyOne] =>
[IdxKeyTwo] =>
[IdxKeyThr] =>
)
where the elements exist, having defined keys but null-values. When using the array later, you would have to drop the dummy-row anyway.

PHP array_merge: argument not an array?

I'm getting some weird behaviour in PHP that I just can't understand.
$count=0;
$temp=array(); //this is definitely a new variable, not that it should matter
foreach($array as $arr) {
if ($arr->bbcode != $previous_bb) {
$previous_bb=$arr->bbcode;
//stuff
$temp=array_merge($temp,$arr);
}
//stuff
}
I've tried to simplify the code a little and just keep what's essential. $array is a 2-D array (so each $arr has some attributes like the bbcode that you see). It complains that argument 1, i.e. $temp, is not an array. Typecasting it to array gives bogus results. Of course, this is within other code, which I can give more details of if needed, but any ideas? I've used the exact same sort of code and syntax in other places and it doesn't complain...
EDIT: Feel free to downvote liberally, had a memory lapse about what I had been working with and how I'd been doing things. Never had to ask a programming question before (in several years), thanks a ton guys, you are immensely fast!
Let's look at your two arguments.
$temp is initialised as array(), and repeatedly assigned to the return value of array_merge which (unless things go wrong) is always an array.
$arr. Well, it's in the name, right? That's about as reliable as $two = 3;. You are accessing $arr->bbcode so it is clearly an object and not an array.
Did you mean $temp[] = $arr;?
You are trying to merge an object ($arr) with an array ($temp). PHP should complain that $arr is not an array. See the example code below:
php > $obj = new StdClass();
php > $obj->property = "value";
php > $arr = [];
php > array_merge($arr, $obj);
Warning: array_merge(): Argument #2 is not an array in php shell code on line 1
Call Stack:
33.2510 230352 1. {main}() php shell code:0
33.2510 230960 2. array_merge() php shell code:1
Typecasting in php is always a bit tricky, if you do so check the type juggling documentation to see what happens when.
Before trying to optimize your code, what do you want to achieve? A new list which is cleaned of duplicate bb codes?

Best way to initialize (empty) array in PHP

In certain other languages (AS3 for example), it has been noted that initializing a new array is faster if done like this var foo = [] rather than var foo = new Array() for reasons of object creation and instantiation. I wonder whether there are any equivalences in PHP?
class Foo {
private $arr = array(); // is there another / better way?
}
$myArray = [];
Creates empty array.
You can push values onto the array later, like so:
$myArray[] = "tree";
$myArray[] = "house";
$myArray[] = "dog";
At this point, $myArray contains "tree", "house" and "dog". Each of the above commands appends to the array, preserving the items that were already there.
Having come from other languages, this way of appending to an array seemed strange to me. I expected to have to do something like $myArray += "dog" or something... or maybe an "add()" method like Visual Basic collections have. But this direct append syntax certainly is short and convenient.
You actually have to use the unset() function to remove items:
unset($myArray[1]);
... would remove "house" from the array (arrays are zero-based).
unset($myArray);
... would destroy the entire array.
To be clear, the empty square brackets syntax for appending to an array is simply a way of telling PHP to assign the indexes to each value automatically, rather than YOU assigning the indexes. Under the covers, PHP is actually doing this:
$myArray[0] = "tree";
$myArray[1] = "house";
$myArray[2] = "dog";
You can assign indexes yourself if you want, and you can use any numbers you want. You can also assign index numbers to some items and not others. If you do that, PHP will fill in the missing index numbers, incrementing from the largest index number assigned as it goes.
So if you do this:
$myArray[10] = "tree";
$myArray[20] = "house";
$myArray[] = "dog";
... the item "dog" will be given an index number of 21. PHP does not do intelligent pattern matching for incremental index assignment, so it won't know that you might have wanted it to assign an index of 30 to "dog". You can use other functions to specify the increment pattern for an array. I won't go into that here, but its all in the PHP docs.
In ECMAScript implementations (for instance, ActionScript or JavaScript), Array() is a constructor function and [] is part of the array literal grammar. Both are optimized and executed in completely different ways, with the literal grammar not being dogged by the overhead of calling a function.
PHP, on the other hand, has language constructs that may look like functions but aren't treated as such. Even with PHP 5.4, which supports [] as an alternative, there is no difference in overhead because, as far as the compiler/parser is concerned, they are completely synonymous.
// Before 5.4, you could only write
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// As of PHP 5.4, the following is synonymous with the above
$array = [
"foo" => "bar",
"bar" => "foo",
];
If you need to support older versions of PHP, use the former syntax. There's also an argument for readability but, being a long-time JS developer, the latter seems rather natural to me.  I actually made the mistake of trying to initialise arrays using [] when I was first learning PHP.
This change to the language was originally proposed and rejected due to a majority vote against by core developers with the following reason:
This patch will not be accepted because slight majority of the core developers voted against. Though if you take a accumulated mean between core developers and userland votes seems to show the opposite it would be irresponsible to submit a patch witch is not supported or maintained in the long run.
However, it appears there was a change of heart leading up to 5.4, perhaps influenced by the implementations of support for popular databases like MongoDB (which use ECMAScript syntax).
Prior to PHP 5.4:
$myArray = array();
PHP 5.4 and higher
$myArray = [];
In PHP an array is an array; there is no primitive vs. object consideration, so there is no comparable optimization to be had.
What you're doing is 100% correct.
In terms of nice naming it's often done that private/protected properties are preceded with an underscore to make it obvious that they're not public. E.g. private $_arr = array() or public $arr = array()
Initializing a simple array :
<?php $array1=array(10,20,30,40,50); ?>
Initializing array within array :
<?php $array2=array(6,"santosh","rahul",array("x","y","z")); ?>
Source : Sorce for the code
There is no other way, so this is the best.
Edit: This answer is not valid since PHP 5.4 and higher.
Try this:
$arr = (array) null;
var_dump($arr);
// will print
// array(0) { }
Do not do this:
$arrTst = array( 'IdxKeyOne' => null, 'IdxKeyTwo' => null, 'IdxKeyThr' => null );
There's no such thing as "initializing" an array's index-keys with dummy/placeholder values. print_r gives:
Array (
[IdxKeyOne] =>
[IdxKeyTwo] =>
[IdxKeyThr] =>
)
where the elements exist, having defined keys but null-values. When using the array later, you would have to drop the dummy-row anyway.

Categories