Multiply and add 2 arrays - php

I have two variables one named $corp_resp:
var_dump($corp_resp)
string(3) "0.3" string(4) "0.35" string(3) "0.4"
Other: $corp_resp_template
var_dump($corp_res_template)ยด
string(3) "0.4" string(3) "0.6" string(3) "0.8"
I want to add and multiply the arrays:
$total = (0.3*0.4)+(0.35*0.6) +(0.4*0.8) => 0,12+0.21+0,32
$total = 0.65
What is the best way to do that?

if both your arrays have the same length you can run something like:
array_sum(array_map(
function($resp, $tpl){ return $resp * $tpl; },
$corp_resp, $corp_res_template));
If the arrays are of unequal length, the tail of the longer array will be evaluated to (number * 0) therefore ignoring them when adding up the final result

Write a function to do it
$corp_resp = array("0.3", "0.35", "0.4");
$corp_res_template = array("0.4", "0.6", "0.8");
function add_products($a1, $a2) {
if (!is_array($a1)) {
throw new Exception("a1 is not an array");
}
if (!is_array($a2)) {
throw new Exception("a2 is not an array");
}
if (sizeof($a1) != sizeof($a2)) {
throw new Exception("Arrays don't have same number of elements");
}
// both params are arrays and have same number of elements!
$count = sizeof($a1);
$multiplied = array();
for($i=0; $i<$count; $i++) {
// we assume that each element is a string representing a floatval so we need to cast as a float before multiplying
$multiplied[$i] = floatval($a1[$i]) * floatval($a2[$i]);
}
return array_sum($multiplied);
}
$val = add_products($corp_resp, $corp_res_template);
var_dump($val);

Related

How to insert array to array PHP

I have arrays, I don't know how to fix
I already try array_push, array_combine, array_merge, but still nothing.
$distance = array(3) {
[0]=>
float(2.2)
[1]=>
float(1.1)
[2]=>
float(3.9)
}
$getID = array(3) {
[0]=>
string(1) "B"
[1]=>
string(1) "C"
[2]=>
string(1) "F"
}
I want to
array(3) {
[0]=> ["B", 2.2]
[1]=> ["C", 1.1]
[2]=> ["F", 3.9]
}
this is my code
function mergeArray($distance, $getID)
{
$mergeArray = array();
for ($i = 0; $i < count($distance); $i++) {
$mergeArray[] = array_splice($getID, $distance[$i]);
}
return $mergeArray;
}
Edited
help me please thx
You don't need "array_combine()", "array_slice()" or similar. Just iterate through the data and create a new one:
$a = [2.2, 1.1, 3.9];
$b = ["B", "C", "F"];
$new = [];
foreach ($a as $index => $value) {
$new[] = [
$b[$index], // Fetch the value with the same index from the other array
$value
];
}
Demo: https://3v4l.org/oseSV
You can use array_map to iterate over two arrays simultaneously and produce a new array:
$distance = array(3) {
[0]=>
float(2.2)
[1]=>
float(1.1)
[2]=>
float(3.9)
}
$getID = array(3) {
[0]=>
string(1) "B"
[1]=>
string(1) "C"
[2]=>
string(1) "F"
}
$output = array_map(function ($d, $id) {
return [$id, $d];
}, $distance, $getID);
Note that this code assumes that both arrays have the same length.
Offtopic:
A little advice about your code: always name your variable with something that allows you to know what's inside it, using correct plural too:
Your $distance variable contains an array off distances, so it nsme should be in plural.
Your $getID is not a function, so it should not be called get, but just $Ids instead.
$distance = [ 2.2, 1.1, 3.9 ];
$getID = [ "B", "C", "F" ];
$result = array_map(fn(string $id, float $distance) => [ $id, $distance ], $getID, $distance);
print_r($result);
For your current code to work you have to:
pass both elements to array_splice function as an array
pass the offset of where the function need to replace the value
as well as the number of how many elements should be removed
You should not reassign $mergeArray because array_splice work with pointer
Checkout the docs for more!
function mergeArray($distance, $getID)
{
$mergeArray = [];
for ($i = 0; $i < count($distance); $i++) {
array_splice($mergeArray,$i,1, [[
$distance[$i],
$getID[$i]
]]);
}
return $mergeArray;
}
however a better approach is to do as in M. Eriksson's ansewar.

Generate 100000 six digit unique alphanumeric code [duplicate]

This question already has answers here:
How to generate a random, unique, alphanumeric string?
(31 answers)
Closed 1 year ago.
I am trying to generate a six character alphanumeric unique code using php. I need to generate 100000 unique codes and push into an array.
So far I have done this
$random_numbers = [];
function random_strings()
{
$str_result ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
while($i <=100000){
array_push($random_numbers,substr(str_shuffle($str_result),0,6));
$i++;
}
print_r($random_numbers);
}
But my server dies when running this code. Do you have any idea, how it can be generated?
Thank you
I fixed the problem. I was declaring the array outside the function
function random_strings()
{
$random_numbers = [];
$str_result ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
while($i <=100000){
array_push($random_numbers,substr(str_shuffle($str_result),0,6));
$i++;
}
print_r($random_numbers);
}
To ensure you get unique strings, you can use the random string as the key to the array instead, then loop till the array has the required number of entries. This code allows you to pass the number of values you want as well as it returns the array rather than just printing it...
function random_strings( $count )
{
$random_numbers = [];
$str_result ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
while( count($random_numbers) < $count ){
$random_numbers[substr(str_shuffle($str_result),0,6)] ='';
}
return array_keys($random_numbers);
}
print_r(random_strings(100000));
Simple two line code for you
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
echo substr(str_shuffle($permitted_chars), 0, 6)
Function example
$n is count of strings
$length is length of each string
function get_random_string($n, $length = 6){
$res = [];
for($i=0; $i<$n; $i++){
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$res[] = substr(str_shuffle($permitted_chars), 0, $length);
}
return $res;
}
Final result
var_dump(get_random_string(10000, 6));
Result of function
array(10) {
[0]=>
string(6) "iIrekz"
[1]=>
string(6) "SG4Bki"
[2]=>
string(6) "5VBhMd"
[3]=>
string(6) "ubqcLr"
[4]=>
string(6) "hPUqng"
[5]=>
string(6) "9xfvpB"
[6]=>
string(6) "m3UQb6"
[7]=>
string(6) "E9nK3Z"
[8]=>
string(6) "1D0ob5"
[9]=>
string(6) "uC2koH"
...
}
Generating random numbers doesn't guarantee uniqueness. Since you want it for coupon codes, you want it to be accurate.
function random_strings() {
$random_numbers = [];
while( count( $random_numbers ) != 100000 ) {
$uniqueString = md5( microtime() );
$requiredLengthString = strtoupper( substr( $uniqueString, 0, 6 ) ); // substring would not be unique
$random_numbers[$requiredLengthString] = NULL; // Putting $requiredLengthString as key so same keys would be overwritten, guaranteeing uniqueness.
}
return array_keys( $random_numbers );
}
print_r( random_strings() );
Inline refactoring if you wish to reduce LOC:
function random_strings() {
$random_numbers = [];
while( count( $random_numbers ) != 100000 ) {
$random_numbers[strtoupper( substr( md5( microtime() ), 0, 6 ) )] = NULL; // Putting this string as key so same keys would be overwritten, guaranteeing uniqueness.
}
return array_keys( $random_numbers );
}
print_r( random_strings() );

How to make an average of array values

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);
}

How to create an array using array_fill function in PHP?

I want to create an array like below
array(2) {
[0]=>
array(2) {
[0]=>
int(1)
[1]=>
int(0)
}
[1]=>
array(2) {
[0]=>
int(2)
[1]=>
int(0)
}
}
Here first element of the inner array will be incremental and second element will always be 0. The outer array length should be 30. I spent a lot of of time on it but couldn't solve it by my one.
Can any one of you help me ?
Thanks
You could do it using array_map() and range():
$o = array_map(function($a) { return array($a, 0); }, range(1, 30));
Demo
The array_fill() function creates an array where all elements are identical. You're asking for an array where the elements aren't all identical, so it's not something you can create simply by using array_fill()....
$array = array_fill(0, 2, array_fill(0, 2, 0));
array_walk($array, function(&$value, $key) { $value[0] = $key+1; });
Maybe you want something like this?
<?php
function initArray() {
$array = array();
for ($i = 1; $i <= 30; $i++) {
$array[] = array($i, 0);
}
return $array;
}
// now call the initArray() function somewhere you need it
$myFancyArray = initArray();
?>

how to order string from HTTP_ACCEPT_LANGUAGE [duplicate]

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.

Categories