I have this array
array(6) {
[0]=>
string(7) "1234567"
[1]=>
string(5) "7548#"
[2]=>
string(9) "1254#abc#"
[3]=>
string(5) "32514"
[4]=>
string(6) "2548##"
[5]=>
string(5) "3258#"
}
I want to validate this data based on provided condition.
If ID(array[0] and array[3] or array[n]) is an integer check the *data* which is(array[1] and array[4] or array[n]) and if that data not contain more then one #, return false;
here is my sample code, but I'm only able to check the first and 2nd array,
if(preg_match('/^[1-7]{1,7}$/', current($arr))){
next($arr);
if(substr_count(next($arr),"#") <=1)
//false
else
echo "true";
}
help needed, thanks.
You can use a for loop, which allows you to control the start point, the condition when to stop and the step your using, so...
$arr = ["1234567", "7548#", "1254#abc#", "32514", "2548##", "3258#"];
for ( $i = 0; $i < count($arr); $i+=3) {
echo $arr[$i].PHP_EOL;
if ( preg_match('/^[1-7]{1,7}$/', $arr[$i]) ) {
if(substr_count($arr[$i+1],"#") > 1) { // Check if it's +1 or +2 here
echo "true".PHP_EOL;
}
else {
echo "false".PHP_EOL;
}
}
}
This loops from the start to the number of elements in your source, but just every 3rd item.
The rest uses similar code to what you've already got, but using the array elements relative to the loop counter ($arr[$i+1] for example). You will have to check if this is the right element you want to check as it may be $arr[$i+2], but the concept is the same.
This outputs..
1234567
false
32514
true
One thing I would recommend is to try and write if statements so that you always get something from it being 'true'. In your code you use <=1 and then there is nothing to do - if you change that round to >1, then it means you can get rid of the 'empty' statement.
you need to create a loop then you can write your rules for specific n.
$n = 3; //Your modulo
for($x = 0, $l = count($array); $x < $l; $x++ ) { //$array is your array
if($x % $n == 0) {
$result = preg_match('/^[1-7]{1,7}$/',$array[$x]);
} else if ($x % $n == 1) {
$result = substr_count($array[$x], '#') > 1;
} else {
$result = true; //no specific rule
}
if(!$result) { //if validation fails
echo "Validation failed";
break;
}
}
Related
$update is a two dimensional associative array. Part of the var_dump is:
array(101) {
[0]=> array(27) { ["code"]=> string(4) "2014" ["na1"]=> string(4) "6010" and many more fields following }
[1]=> array(27) { ["code"]=> string(4) "2015" ["na1"]=> string(4) "6010" and many more fields following }
and many more subarrays following of course . . .
Need to replace the code value with a name and created:
foreach($update as $key=>$subarray){;
foreach ($subarray as $subkey=>$val) {
echo $subkey.$val."<br>";//Just for checking
if ($subkey=='code' && $val==2014)
{
$val="Name1";
}
elseif ($key=='code' && $val==2015)
{
$val="Name2";
}
}
}
var_dump($update);
The echo $subkey and $val give perfectly the correct values, however de If statement seems never to be true (or is cancelled out again somehow) as the var_dump is leading again to the original values
Some Stackoverflow research even showed constructions with only one foreach loop, much more elegant, but seems not to reach the second array level.
Is there a better approach? Solution to fix this one?
You are not updating the source array.
foreach($update as $key=>$subarray){
foreach ($subarray as $subkey=>$val) {
echo $subkey.$val."<br>";//Just for checking
if ($subkey=='code' && $val==2014)
{
//$val="Name1";
$update[$key][$subkey] = "Name1" ;
}
elseif ($key=='code' && $val==2015)
{
//$val="Name2";
$update[$key][$subkey] = "Name2" ;
}
}
}
You can access to the field you want by index.
Example :
$i = 0;
$j = 0;
foreach($update as $key=>$subarray){;
foreach ($subarray as $subkey=>$val) {
echo $subkey.$val."<br>";//Just for checking
if ($subkey=='code' && $val==2014)
{
$update[$i][$j] = "Name1";
}
elseif ($key=='code' && $val==2015)
{
$update[$i][$j] = "Name2";
}
$j++
}
$j = 0;
$i++;
}
var_dump($update);
$newArr = array();
foreach($update as $key=>$subarray){
$subNewArr = array();
foreach ($subarray as $item) {
if ($item['code']==2014)
{
$item['code']="Name1";
}
elseif ($item['code']==2015)
{
$item['code']="Name2";
}
array_push($subNewArr, $item);
}
array_push($newArr, $subNewArr);
}
var_dump($update);
Less if else checking
I have a database with multiple records. It is structured like this:
["data"]=>
array(5) {
[1]=>
[2]=>
array(11) {
[0]=>
string(1) "0"
[1]=>
string(8) "25000000"
[2]=>
string(3) "day"
[3]=>
string(5) "0.00%"
[4]=>
string(9) "404049904"
[5]=>
string(1) "0"
[6]=>
string(5) "0.00%"
[7]=>
string(1) "0"
[8]=>
string(1) "0"
[9]=>
string(1) "0"
[10]=>
string(3) "0.0"
}
I need to fetch the 8th record and I do this by using
public static function($data)
{
$array = [];
$path = $data->data[2];
foreach($path as $key => $item)
if($key > 1)
{
$array[] = [$item->data[8]];
}
return json_encode($array);
}
This foreach takes all the 8th values from the array but I need to display a single number which is the average of all the 8th values. How can I do this?
Once you've got your array containing all your data, simple sum the array and then divide by the size of the array.. something along these lines
$average = (array_sum($array) / count($array));
Of course you may want to check for count($array) being 0;
Because you put your value into a new array, you can not use array_sum to sum the values, so you should store it.
$sum = 0;
foreach($path as $key => $item)
if($key > 1) {
$array[] = [$item->data[8]];
$sum += $item->data[8];
}
}
$avg = ($sum / count($array); //the average
var_dump($avg);
If is it possible, just put it as a value:
$array[] = $item->data[8]; //no wrapping []
In this case, you can use $avg = array_sum($array) / count($array);
if (count($array)>0){
$avg = array_sum($array) / count($array);
}
I would personally do those calculations in the database before the data gets to your PHP script itself. See AVG().
If you can't for some reason use that I would output those values into a flat array and then just calculate the average. So something like :
function getAverage($data) {
$flatArray = array();
foreach ($data as $row) {
if (!empty($row->8)) {
$flatArray[] = $row->8;
}
}
return (array_sum($flatArray)/count($flatArray));
}
EDIT: Moved to Object traversing on the data row, sorry, missed that initially and thought it was an array in all the nests.
Since you have a loop within your static Method; why not do the calculation therein and return it or add it to the JSON Data if You need your Data in JSON Format? Here's what's implied by the above:
public static function getAverageSum($data) {
$array = [];
$path = $data->data[2];
$sumTotal = 0.00; //<== YOU COULD JUST SUM IT DIRECTLY WITHOUT USING AN ARRAY
foreach($path as $key => $item) {
if ($key > 1) {
$array[] = $item->data[8];
$sumTotal += floatval($item->data[8]);
}
}
// IF YOU ARE ONLY INTERESTED IN THE AVERAGE SUM YOU COULD EVEN ADD IT IT TO THE $array AS AN EXTRA KEY
// LIKE SO:
$arrLen = count($array);
$array['avgSum'] = $sumTotal/$arrLen;
// IF YOU NEED YOUR DATA IN JSON... THEN RETURN THE JSON ENCODED DATA WITH SUM AS PART OF THE DATA.
// YOU'D HAVE NO NEED FOR array_sum() SINCE YOU DID YOUR PREP-WORK ALREADY...
return json_encode($array);
// ALTERNATIVELY; IF ALL YOU NEED IS JUST THE AVERAGE SUM; YOU COULD AS WELL DIRECTLY RETURN $sumTotal/$arrLen
return ($sumTotal/$arrLen);
}
This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 8 years ago.
I checked all the questions which have already been asked. I did not find the suitable one. The question is to sort and rsort an array but use sort and rsort unfunction is not allowed. It supposed to be done with for loop.
<?php
$numberstring = $_GET['numberstring'];
$array = explode(',',$numberstring);
echo "Order in the beginning: $numberstring\n";
// My code starts from here for the missing part
for ($i=0;$i<count($array);$i++)
{
if ($get_largest<$array[$i])
{$get_largest=$array[$i];
$get_largest=range(0,count($array));//I 'm not sure of this line
}
if ($get_smallest>$array[$i])
{
$get_smallest=$array[$i];
$get_smallest=range(0,count($array));
}
}
$largest_smallest=explode(',',$get_largest);
$smallest_largest=explode(' ,',$get_smallest);
// my code finished
echo "Largest to smallest: $largest_smallest\n";
echo "Smallest to largest: $smallest_largest\n";
?>
The easiest way I can imagine would be using the min() and max() function.
Here's the example:
<?
function array_sort($input,$reverse){
unset($new_array);
$new_array = array(); // This will be our output where sorted values coming in //
if($reverse == false){ // RSort or not //
for($i=0;$i<count($input);$i){ // loop as many times as many values are stored in the array //
$get_smallest = min($input); // get the smallest value of the input array //
$key = array_search($get_smallest, $input); // get the index of the smallest array to unset it later //
$new_array[] = $get_smallest; // store the smallest value in a new array //
unset($input[$key]); // unset (delete) the extracted (smallest) value so the min()-function grabs the next one in the next loop //
}
}
else{ // RSort or not //
for($i=0;$i<count($input);$i){
$get_biggest = max($input);
$key = array_search($get_biggest, $input);
$new_array[] = $get_biggest;
unset($input[$key]);
}
}
return $new_array;
}
$unsorted_array = array( 'ab','aa','ac','bf','be'); // Our test array
$output1 = array_sort($unsorted_array,false);
$output2 = array_sort($unsorted_array,true);
var_dump($output1);
echo '<br><br>';
var_dump($output2);
?>
Output: 1
array(5) {
[0]=> string(2) "aa"
[1]=> string(2) "ab"
[2]=> string(2) "ac"
[3]=> string(2) "be"
[4]=> string(2) "bf"
}
Output: 2
array(5) {
[0]=> string(2) "bf"
[1]=> string(2) "be"
[2]=> string(2) "ac"
[3]=> string(2) "ab"
[4]=> string(2) "aa"
}
So, with this function you can sort any array in normal and reversed mode.
I havnt commented the reversed block. Its just the same as the block above but with max() instead of min().
Greetings.
This is the bubble sort program I learned a long time ago. Probably easier ways to do it, but it works. I've included prints so you can see what is going on as the arrays change.
<?php
$numbers = '2,24,21,2,3,77,900,1,4,5';
$array = explode(',',$numbers);
function bubblesort($numbers){
$array['mintomax'] = $numbers;
$array['maxtomin'] = $numbers;
while(true){
$shift_detected = false;
for($i=0;$i<count($numbers)-1;$i++){
$next_Var = $i+1;
if($array['mintomax'][$i]>$array['mintomax'][$next_Var]){
echo $i.': '.$next_Var.':';
$hold_var = $array['mintomax'][$i];
$array['mintomax'][$i] = $array['mintomax'][$next_Var];
$array['mintomax'][$next_Var] = $hold_var;
$shift_detected = true;
print_r($array['mintomax']);
echo '<br />';
}
}
if(!$shift_detected){
echo '<br /><br />';
break;
}
}
while(true){
$shift_detected = false;
for($i=0;$i<count($numbers);$i++){
$next_Var = $i+1;
if($array['maxtomin'][$i]<$array['maxtomin'][$next_Var]){
echo $i.': '.$next_Var.':';
$hold_var = $array['maxtomin'][$i];
$array['maxtomin'][$i] = $array['maxtomin'][$next_Var];
$array['maxtomin'][$next_Var] = $hold_var;
$shift_detected = true;
print_r($array['maxtomin']);
echo '<br />';
}
}
if(!$shift_detected){
echo '<br /><br />';
break;
}
}
return $array;
}
print_r(bubblesort($array));
?>
I have a plain string like this:
1 //here is a number defines phrase name
09/25/2013 //here is a date
<i>some text goes here</i> //and goes text
2
09/24/2013
text goes on and on
4 //as you can see, the numbers can skip another
09/23/2013
heya i'm a text
I need to create array from this but the numbers that defines phrases must give me the date of that line and return the text when i called it. Like,
$line[4][date] should give me "09/23/2013"
Is that possible, if possible can you explain me how to do this?
$stringExample = "1
09/25/2013
<i>some text goes here</i>
2
09/24/2013
text goes on and on
and on and on
4
09/23/2013
heya i'm a text";
$data = explode("\r\n\r\n", $stringExample);
$line = array();
foreach ($data as $block) {
list($id, $date, $text) = explode("\n", $block, 3);
$index = (int) $id;
$line[$index] = array();
$line[$index]["date"] = trim($date);
$line[$index]["text"] = trim($text);
}
var_dump($line) should output:
array(3) {
[1]=>
array(2) {
["date"]=>
string(10) "09/25/2013"
["text"]=>
string(26) "<i>some text goes here</i>"
}
[2]=>
array(2) {
["date"]=>
string(10) "09/24/2013"
["text"]=>
string(34) "text goes on and on
and on and on"
}
[4]=>
array(2) {
["date"]=>
string(10) "09/23/2013"
["text"]=>
string(15) "heya i'm a text"
}
}
You can test it here.
If the structure of the file is a coerent pattern of rows, with PHP you read each line and each 1st you have the number, each 2nd you have the date, each 3rd you have the text, each 4th you have empty, you reset the counter to 1 and go on like that, and put values in arrays, using even an external index, or the 1st line (number) as index.
try this:
EDIT: should now work for multi line text.
//convert the string into an array at newline.
$str_array = explode("\n", $str);
//remove empty lines.
foreach ($str_array as $key => $val) {
if ($val == "") {
unset($str_array[$key]);
}
}
$str_array = array_values($str_array);
$parsed_array = array();
$count = count($str_array);
$in_block = false;
$block_num = 0;
$date_pattern = "%[\d]{2}/[\d]{2}/[\d]{2,4}%";
for ($i = 0; $i < $count; $i++) {
//start the block at first numeric value.
if (isset($str_array[$i])
&& is_numeric(trim($str_array[$i]))) {
// make sure it's followed by a date value
if (isset($str_array[$i + 1])
&& preg_match($date_pattern, trim($str_array[$i + 1]))) {
//number, followed by date, block confirmed.
$in_block = true;
$block_num = $i;
$parsed_array[$str_array[$i]]["date"] = $str_array[$i + 1];
$parsed_array[$str_array[$i]]['text'] = "";
$i = $i + 2;
}
}
//once a block has been found, everything that
//is not "number followed by date" will be appended to the current block's text.
if ($in_block && isset($str_array[$i])) {
$parsed_array[$str_array[$block_num]]['text'].=$str_array[$i] . "\n";
}
}
var_dump($parsed_array);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
HTTP_ACCEPT_LANGUAGE
i try to code a language option tool. therefor i use
$default_language = (strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]));
if (eregi('af', $default_language)) {do something}
now i would like to order the string when i will echo:
$_SERVER["HTTP_ACCEPT_LANGUAGE"]
for example an user has specified a number of languages.
example for chrome with different languages:
nl,en-gb;q=0.8,en;q=0.6,fr;q=0.4,fr-ca;q=0.2
so how can i read out the string to bring it in a certain order where i can see that nl is the first language that is prefered.
the code should be something like:
if ('nl'== array[0]) {do something}
so if there is someone who could help me out i really would appreciate.
thanks alot.
From HTTP/1.1 Header Field Definitions:
Each language-range MAY be given an associated quality value which represents an estimate of the user's preference for the languages specified by that range. The quality value defaults to "q=1".
You have to loop over languages and select one with highest quality (preferrence); like this:
$preferred = "en"; // default
if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
{
$max = 0.0;
$langs = explode(",", $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
foreach($langs as $lang)
{
$lang = explode(';', $lang);
$q = (isset($lang[1])) ? ((float) $lang[1]) : 1.0;
if ($q > $max)
{
$max = $q;
$preferred = $lang[0];
}
}
$preferred = trim($preferred);
}
// now $preferred is user's preferred language
If Accept-Language header is not sent, all languages are equally acceptable.
How about explode()?
$array = explode(",",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
Given your example string, you should end up with the following values
$array[0] = "nl"
$array[1] = "en-gb;q=0.8"
$array[2] = "en;q=0.6"
etc.
If you prefer to assume that the string is not always ordered before it is sent by the browser then the following code will parse and sort it. Note that I've changed French's q to 0.9.
<?php
$lang = 'nl,en-gb;q=0.8,en;q=0.6,fr;q=0.9,fr-ca;q=0.2';
$langs = array();
foreach(explode(',', $lang) as $entry) {
$t1 = explode(';', $entry);
switch( count($t1) ) {
case 1:
$langs[] = array($t1[0], 1.0);
break;
case 2:
$t2 = explode('=', $t1[1]);
$langs[] = array($t1[0], floatval($t2[1]));
break;
default:
echo("what is this I don't even");
break;
}
}
function mysort($a, $b) {
if( $a[1] == $b[1] ) { return 0; }
elseif( $a[1] > $b[1] ) { return -1; }
else { return 1; }
}
usort($langs, 'mysort');
var_dump($langs);
Output:
array(5) {
[0]=>
array(2) {
[0]=>
string(2) "nl"
[1]=>
float(1)
}
[1]=>
array(2) {
[0]=>
string(2) "fr"
[1]=>
float(0.9)
}
[2]=>
array(2) {
[0]=>
string(5) "en-gb"
[1]=>
float(0.8)
}
[3]=>
array(2) {
[0]=>
string(2) "en"
[1]=>
float(0.6)
}
[4]=>
array(2) {
[0]=>
string(5) "fr-ca"
[1]=>
float(0.2)
}
}
try this :
<?php
print_r(Get_Client_Prefered_Language(true, $_SERVER['HTTP_ACCEPT_LANGUAGE']));
function Get_Client_Prefered_Language ($getSortedList = false, $acceptedLanguages = false)
{
if (empty($acceptedLanguages))
$acceptedLanguages = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
// regex borrowed from Gabriel Anderson on http://stackoverflow.com/questions/6038236/http-accept-language
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $acceptedLanguages, $lang_parse);
$langs = $lang_parse[1];
$ranks = $lang_parse[4];
// (recursive anonymous function)
$getRank = function ($j)use(&$getRank, &$ranks)
{
while (isset($ranks[$j]))
if (!$ranks[$j])
return $getRank($j + 1);
else
return $ranks[$j];
};
// (create an associative array 'language' => 'preference')
$lang2pref = array();
for($i=0; $i<count($langs); $i++)
$lang2pref[$langs[$i]] = (float) $getRank($i);
// (comparison function for uksort)
$cmpLangs = function ($a, $b) use ($lang2pref) {
if ($lang2pref[$a] > $lang2pref[$b])
return -1;
elseif ($lang2pref[$a] < $lang2pref[$b])
return 1;
elseif (strlen($a) > strlen($b))
return -1;
elseif (strlen($a) < strlen($b))
return 1;
else
return 0;
};
// sort the languages by prefered language and by the most specific region
uksort($lang2pref, $cmpLangs);
if ($getSortedList)
return $lang2pref;
// return the first value's key
reset($lang2pref);
return key($lang2pref);
}
The languages are ordered as the user prefers them. All you have to do is to split the string at the , symbol and from the parts, get rid off everything from the ; to the end (including the ;) and you have the languages in the user's prefered order.