I am trying to count the values of an associative array, but it isnt doing what I want it to.
I am pulling data from a database, as I need all the answers to a question. The answers in the database are under the fields answer1, answer2, answer3 etc, up to answer20.
What I am trying to do is count the number of fields that contain data, and ignore the fields that dont have any data.
Here is my code so far:
<?php
$results = $db->get_results("SELECT * FROM wellness_hra_questions WHERE category='general' AND level='1' AND gender='All' AND active='yes' ORDER BY id ASC");
foreach($results as $result){
$id = $result->id;
}
$answers = $db->get_results("SELECT answer1, answer2, answer3, answer4, answer5, answer6, answer7, answer8, answer9, answer10, answer11, answer12, answer13, answer14, answer15, answer16, answer17 FROM wellness_hra_questions WHERE id=".$id."");
//$db->debug();
for( $i=1; $i <= 17; $i++) {
foreach($answers as $a_result){
$answer = 'answer';
$answer_id = $answer.$i;
$answer_id2 = $a_result->$answer_id;
$answer1 = $a_result->answer1;
$array1 = array('1'=>''.$answer1.'');
$answer2 = $a_result->answer2;
$array2 = array('2'=>''.$answer2.'');
$answer3 = $a_result->answer3;
$array3 = array('3'=>''.$answer3.'');
$answer4 = $a_result->answer4;
$array4 = array('4'=>''.$answer4.'');
$answer5 = $a_result->answer1;
$array5 = array('5'=>''.$answer5.'');
$answer6 = $a_result->answer6;
$array6 = array('1'=>''.$answer6.'');
}
if($answer1 == TRUE){
$newvalue1 = $array1;
}
if($answer2 == TRUE){
$newvalue2 = $array2;
}
if($answer3 == TRUE){
$newvalue3 = $array3;
}
if($answer4 == TRUE){
$newvalue4 = $array4;
}
if($answer5 == TRUE){
$newvalue1 = $array5;
}
if($answer1 == TRUE){
$newvalue6 = $array6;
}
$newarray = array_merge($newvalue1,$newvalue2, $newvalue3, $newvalue4, $newvalue5);
$count = count($newarray, COUNT_RECURSIVE);
echo $count;
}
?>
You need a code cleanup here - if what you want is a count, and the array_merge is ONLY for this purpose, this should do what I believe you would like to do:
for( $i=1; $i <= 17; $i++) {
foreach($answers as $a_result){
$answer_id = 'answer'.$i;
$answer_id2 = $a_result->$answer_id;
$thisCount = 0;
$newarray = array();
for($j = 1; $j < 7; $j++) {
$var = "answer" . $j;
$$var = ${"a_result->answer" . $j};
if (strlen($$var) > 0) {
$arrayID = "array" . $j;
$$arrayID = array((string)$j => $$var);// I don't think you need this but if you do included array_merge here
array_merge($newarray, $$arrayID);
$thisCount++;
}
}
echo $count;
print_r($newarray); // show the contents of the merged arrays
}// end foreach
}//end for
Related
I need to store service_ids and country_ids in an array in this format
array
[0]["service_id"] should give service id at 0th
index
array[0]["country_id"] should give me country id at 0th index and so on.
function service_ids($conn) {
$ids = array();
$sql = "SELECT id from services";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) {
array_push($ids, $row["id"]);
}
return $ids;
}
$service_ids = service_ids($conn);
function country_ids($conn) {
$ids = array();
$sql = "SELECT id FROM countries";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) {
array_push($ids, $row["id"]);
}
return $ids;
}
$country_ids = country_ids($conn);
`//I am having problem here how to store it.
$z = array();
for ($i=0; $i < count($service_ids); $i++) {
$z = array(`
array("service_id"=>$service_ids[$i], "country_id"=>$country_ids[$i])
);
}
print_r($z);
?>
You are basically overwriting array in each iteration in final loop, instead of that store new array in new array index
$z = array();
$counter = 0;
for ($i=0; $i < count($service_ids); $i++) {
$counter = count($z);
$z[$counter]["service_id"] = $service_ids[$i];
$z[$counter]["country_id"] = $country_ids[$i];
}
How do I make sure that the password contains at least one character from each array? I could use do..while, right? What I don't quite understand is what I will need to put in the if statement inside do...while.
Is do...while the only way to ensure at least one character from each array is in the final password or are there other ways?
$length = 6;
$a1 = str_split('0123456789');
$a2 = str_split('%^*+~?!');
$a3 = str_split('abcdefghigklmnopqrstuvwxyz');
$result = ""; //final random password
for($i = 0; $i < $length; $i++){
$values = [$a1,$a2,$a3];
$chosen = array_rand($values);
$result .= $values[$chosen][array_rand($values[$chosen])];
}
echo $result;
$length = 6;
$a1 = str_split('0123456789');
$a2 = str_split('%^*+~?!');
$a3 = str_split('abcdefghigklmnopqrstuvwxyz');
$resultArr[] = $a1[array_rand($a1)];
$resultArr[] = $a2[array_rand($a2)];
$resultArr[] = $a3[array_rand($a3)];
for($i = 0; $i < $length-3; $i++){
$values = [$a1,$a2,$a3];
$chosen = array_rand($values);
$resultArr[] = $values[$chosen][array_rand($values[$chosen])];
}
shuffle($resultArr);
$result = implode($resultArr); //final random password
echo $result;
You can surround the for wit ha do..while and in the condition check with preg_match() and a regex pattern that checks if at least one character is in the result:
<?php
$length = 6;
$a1 = str_split('0123456789');
$a2 = str_split('%^*+~?!');
$a3 = str_split('abcdefghigklmnopqrstuvwxyz');
$result = ""; //final random password
do {
for($i = 0; $i < $length; $i++){
$values = [$a1,$a2,$a3];
$chosen = array_rand($values);
$result .= $values[$chosen][array_rand($values[$chosen])];
}
} while(!(preg_match('/^(?=.*?[0-9])(?=.*?[a-z])(?=.*?[%*+?!]).{1,}/', $result)));
echo $result;
If the there's no coincidences with the pattern using preg_match, then will return false, in the do..while condition we check if one preg_match is false, if it is, do it again.
I made my answer general for any number of arrays.
I would use preg_match() for this, but for the question you asked, yes, you need to check each array separately:
$user_inputted_password = $_POST['user_inputted_password'];
$length = strlen($user_inputted_password); // user input password - you are capturing this somewhere, right
$a1 = str_split('0123456789');
$a2 = str_split('%^*+~?!');
$a3 = str_split('abcdefghigklmnopqrstuvwxyz');
$validate = array();
$result = ""; //final random password
function populate_validation_array($match_num, &$validate) {
if (!in_array($match_num, $validate)) {
$validate[] = $match_num;
}
}
$numeric_indexes = array(1, 2, 3);
$index_count = count($numeric_indexes);
for($i = 0; $i < $length; $i++){
for($j = 0; $j < $index_count; $j++) {
$numeric_index = $numeric_indexes[$j];
if (in_array($user_inputted_password[$i], ${"a" . $numeric_index})) {
populate_validation_array($numeric_index, $validate);
}
}
}
if (count($validate) === $index_count) {
$values = array();
for($i = 0; $i < $index_count; $i++) {
$values[] = ${"a" . ($i + 1)};
}
$chosen = array_rand($values);
$result .= $values[$chosen][array_rand($values[$chosen])];
}
echo $result;
I have a $nr variable that as the number of arrays with the same name that i created in a previous function, something like this:
$var = 'sorteios_'.$nr;
$$var = array($sorteio_id);
I have it in a While function so it was created something like 3 arrays with the names:
$sorteios_1 , $sorteios_2 , $sorteios_3
And i want to add them inside an array_merge, so i have to use the $nr that says how many arrays with the same name were created.
$nr = 3;
i want that the final result looks something like this.
$result = array_merge($sorteios_1, $sorteios_2, $sorteios_3);
That's the whole function if you want to check it (it's not complete because of the problem i'm having):
function check_sorteios(){
global $db;
$id = $_SESSION['userid'];
$query1 = "SELECT * FROM sorteios WHERE userid = $id";
$result1 = $db->query($query1);
$count = $result1->rowCount();
if ($count == 0){ $sorteios = 0; echo "sem sorteios";}
else{
$numero = 0;
$sorteios = 0;
$nr = 0;
while($row1 = $result1->fetch()){
if ( $numero == $count ){ return 0;}
$numero++;
$sorteio_id = $row1['id'];
$query2 = "SELECT * FROM productos WHERE id = $sorteio_id";
$result2 = $db->query($query2);
while($row2 = $result2->fetch()){
$data = $row2['data'];
$titulo = $row2['titulo'];
if (strtotime($data) > time()){
if(!isset($$sorteio_id)){
$$sorteio_id = 1;
}
$nr++;
$var = 'sorteios_'.$nr;
$$var = array($sorteio_id);
}
}
}
}
$result = array_merge($sorteios_1, $sorteios_2, $sorteios_3);
$occurences = array_count_values($result);
print_r($occurences);
}
You could try to create a string containing the code executing array_merge of all your arrays and then pass it to the eval function (http://it1.php.net/manual/it/function.eval.php)...
Something like this:
$str="\$result=array_merge(";
for($i=1;$i<=$nr;$i++){
$str.="\$sorteios_$i,";
}
$str=substr($str,0,-1);
$str.=");";
eval($str);
Then in $result you have what you need.
Is there a reason you can't recursively merge?
if ($nr > 0) {
$result = $sorteios_1;
for ($i = 2; $i <= $nr; ++$i) {
$result = array_merge($result, ${'sorteios_'.$i});
}
} else {
// you might want to handle this case differently
$result = array();
}
I have code which pretty much does this.....
//get the row info
$Row1 = $FullTable->find('div[class=ismPitchRow1]',0);
$Row2 = $FullTable->find('div[class=ismPitchRow2]',0);
$Row3 = $FullTable->find('div[class=ismPitchRow3]',0);
$Row4 = $FullTable->find('div[class=ismPitchRow4]',0);
$Row5 = $FullTable->find('div[class=ismPitchRow5]',0);
//Loop 5 times. One for each row on the pitch.
for ($i=1; $i<=5; $i++)
{
if ($i = 1) { echo $Row1; }
if ($i = 2) { echo $Row2; }
if ($i = 3) { echo $Row3; }
if ($i = 4) { echo $Row4; }
if ($i = 5) { echo $Row5; }
}
It works, but as you can see it's not very efficient and badly designed. How would I simplify this? I know there are much smaller ways that these kind of loops can be done.
Thanks.
use the great invention of arrays:
//get the row info
$Row[1] = $FullTable->find('div[class=ismPitchRow1]',0);
$Row[2] = $FullTable->find('div[class=ismPitchRow2]',0);
$Row[3] = $FullTable->find('div[class=ismPitchRow3]',0);
or, even more clever...
for ($i = 1; $i <= 5; $i++) {
$find = "div[class=ismPitchRow$i]";
$Row[$i] = $FullTable->find($find,0);
}
do the same for echoing:
for ($i = 1; $i <= 5; $i++) {
echo $Row[$i];
}
but why not do everything in 1 loop?
for ($i = 1; $i <= 5; $i++) {
$find = "div[class=ismPitchRow$i]";
echo $FullTable->find($find,0);
}
I would store $Row1 through $Row5 in an array and iterate through it with a foreach loop.
<?php
$YourArray = array();
array_push($YourArray,$FullTable->find('div[class=ismPitchRow1]',0),$FullTable->find('div[class=ismPitchRow2]',0),$FullTable->find('div[class=ismPitchRow3]',0),$FullTable->find('div[class=ismPitchRow4]',0),$FullTable->find('div[class=ismPitchRow5]',0));
foreach($YourArray as $row){
echo $row;
}
?>
Ive got 2 arrays, first one contains values of objects, and second one contains their IDs.
In this form:
$values[0] applies to $ids[0]
$values[1] applies to $ids[1]
I need to sort first array (using sort() ) from lowest to highest (values are ints) - That's not problem.
Problem is, that When I sort array with values, I will lost ID of that value.
My question is: How to make that
If $values[0] turns to $values[5], automatically turn $ids[0] to $ids[5]
Thanks
Update:
Content of $values and $ids:
$values[0] = 1.5;
$values[1] = 2.4;
$values[2] = 15.7;
$values[3] = 11.7;
$values[4] = 4.8;
$values[5] = 0.4;
$ids[0] = 1;
$ids[1] = 2;
$ids[2] = 3;
$ids[3] = 4;
$ids[4] = 5;
$ids[5] = 6;
Combine the arrays first, then sort by key:
$newArr = array_combine($ids, $values);
ksort($newArr);
It sounds like you're looking for array_combine():
Example
<?php
$ids = array(2, 1, 3); // IDs
$values = array(a, b, c); // Values
$array = array_combine($ids, $values); // Combine arrays as ID => Value
ksort($arrays); // Sort new array
print_r($array); // Echo array
Output
Array
(
1 => b,
2 => a,
3 => c,
)
Follow the code below... have not tested it ... but it must work.... Easy to understand..
<?php
$count = count($values);
for($i = 0; $i<$count; $i++)
{
if($i == 0)
{
$sort1 = $values[$i];
$sort2 = $ids[$i];
$temp = 0;
}
if($sort1 > $values[$i])
{
$sort1 = $values[$i];
$sort2 = $ids[$i];
$temp_val = $values[$temp];
$temp_id = $ids[$temp];
$values['temp'] = $values[$i];
$ids['temp'] = $ids[$i];
$temp = $i;
$values[$i] = $temp_val;
$ids[$i] = $temp_id;
}
}
?>