I'v written 2 codes to shuffle some arrays whitch are in a for loop
First:
$numbers = range(0, sizeof($array_id)-1);
shuffle($numbers);
foreach ($numbers as $number) {
$arr = array("user" => array("id" => $array_id[$number], "name" => $array_name[$number], "key" => $array_key[$number]));
}
echo json_encode($arr);
This one has a big problem and that's if the $number in one of the arrays equals to 5 it won't loop to put another result of $number in the that array, for example the result would be something like this:
{"user":{"id":["18","2","36"],"name":["alex","john"],"key":["159","228,"486,"852"]]}}
All of my arrays have 5 values in them and you can see it returned them defectively.I'll be thankful if anyone can tell me why when $number gets the max value in range by shuffle and array gets that $number it stocks?
Second:
function shuffle_assoc(&$array) {
if (shuffle($array)) {
return $array;
}else{
return FALSE;
}
}
for ($y=0; $y<sizeof($array_id); $y++) {
$arr = array("user" => array("id" => shuffle_assoc($array_id), "name" => shuffle_assoc($array_name), "key" => shuffle_assoc($array_key)));
}
echo json_encode($arr);
This one works fine But I want the id and name to be match I mean they shuffle the same(if $array_id[2] then array_name[2]) that's why I wrote the first code.anyway for this one if anyone knows how to make id and name shuffle the same I'll be appreciate that.(sorry if I had mistakes in my writing my first language isn't English but I love English :)
I'm not sure that I completely understood you, but
$numbers = range(0, 5);
// $number = array(0, 1, 2, 3, 4, 5)
All of my arrays have 5 values
It's
$array_id[0]
$array_id[1]
$array_id[2]
$array_id[3]
$array_id[4]
So you haven't $array_id[5]. I think you need $numbers = range(0, 4);
EDIT:
Once again, I'm not sure if you want this to happen.
<?php
$array_id = array(1,2,3,4,5);
$array_name = array('a','b','c','d','e');
$numbers = range(0, 4);
shuffle($numbers);
$arr = array();
foreach ($numbers as $number) {
$arr["id"][] = $array_id[$number];
$arr["name"][] = $array_name[$number];
}
$arr2 = array("user" => array("id" => $arr["id"], "name" => $arr["name"]));
echo json_encode($arr2);
?>
Related
I want to rank the keys of an associative array in php based upon their values. (top to down as 1, 2, 3....). Keys having same value will have same rank.
Here function getRanks() is meant to return an array containing keys and the ranks (number).
I expect it to return like this (this is sorted value wise in descending)
Array
(
[b] => 1
[a] => 2
[d] => 3
[c] => 3
[e] => 4
)
There is issue in assigning the ranks (values) in the $ranks array which is to be returned.
What am I doing wrong? Do these loops even do something?
Code:
$test = array('a'=> 50, 'b'=>60, 'c'=>20, 'd'=>20, 'e'=>10);
$json = json_encode($test);
print_r(getRanks($json));
function getRanks($json) {
$tmp_arr = json_decode($json, TRUE);
$ranks = array();
uasort($tmp_arr, function($a, $b){
return $a == $b ? 0 : $a > $b ? -1 : 1; //descending
});
$keys = array_keys($tmp_arr); //after sorting
$ranks = array_fill_keys($keys, 0); //copy keys
$ranks[$keys[0]] = 1; //first val => rank 1
//------- WORKS FINE UNTIL HERE ------------------
// need to fix the ranks assignment
for($i=1; $i<count($keys)-1; $i++) {
for($j=$i; $j < count($keys)-1; $j++) {
if($tmp_arr[$keys[$j]] == $tmp_arr[$keys[$j+1]]) {
$rank[$keys[$j]] = $i;
}
}
}
return $ranks;
}
Your approach seems unnecessarily complicated. In my version I kept the json-related copying part of it but finished it off in a simpler way:
function getRanks($json) {
$tmp_arr = json_decode($json, TRUE);
asort($tmp_arr);. // sort ascending
$i=0; $lv=null;$ranks = array();
foreach ($tmp_arr as $k=>$v) {
if ($v>$lv){ $i++; $lv=$v;}
$ranks[$k]=$i;
}
return $ranks;
}
See the demo here: https://rextester.com/LTOA23372
In a slightly modified version you you can also do the ranking in a descending order, see here: https://rextester.com/HESQP10053
I've also tried with another approach.
I think it may not be the good solution because of high memory & CPU time consumption.
For small arrays (in my case) it works fine.
(I've posted because it may be an answer)
It creates array of unique values and fetches ranks accordingly.
$test = array('a'=> 50, 'b'=>60, 'c'=>20, 'd'=>20, 'e'=>10);
$json = json_encode($test);
print_r(getRanks($json));
function getRanks($json) {
$tmp_arr = json_decode($json, TRUE);
arsort($tmp_arr);
$uniq_vals = array_values(array_unique($tmp_arr)); // unique values indexed numerically from 0
foreach ($tmp_arr as $k => $v) {
$tmp_arr[$k] = array_search($v, $uniq_vals) + 1; //as rank will start with 1
}
return $tmp_arr;
}
This is the simple thing that you can do it by using php array function check example given below.
<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
asort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
I have a code like this:
Lets assume that this arrays has this values:
$arr1 = array();
$arr2 = array();
$result = array();
$arr1[] = array( 'grade' => [1,2,3,4] );
$arr2[] = array( 'grade' => [1,2,3,4] );
foreach($arr1 as $a1){
$set1 = $a1['grade'];
foreach($arr2 as $a2){
$set2 = $a2['grade'];
}
$result[] = array('show_result' => $set1+$set2);
}
foreach{$result as $res){
echo $res['show_result'];
}
The output of the array $res['show_result'] must be:
2, 4, 6, 8
But I get the wrong addition of this arrays. Help will be much appreciated.
As Joni said, your first error is on line 3: ' should be ;
Then, you're not filling arrays like you wanted : array( 'grade' => 1,2,3,4 ); creates an array with first key is 'grade' with value '1', then second key is '0' with value '2' etc...
Your last foreach loop has a syntax error similar to your first error.
See a working correction here
$arr1 = array();
$arr2 = array();
$result = array();
array_push($arr1, 1, 2, 3, 4); //fill array with 4 values (integers)
array_push($arr2, 1, 2, 3, 4); //fill array with 4 values (integers)
//so $arr1 & $arr2 are now a 4 elements arrays
$length = count($arr1); //size of array, here 4
for ($i = 0; $i < $length; $i++) { //loop over arrays
array_push($result, ($arr1[$i] + $arr2[$i])); //fill the results array with sum of the values from the same position
}
var_dump($result);
You have quite a few syntax errors in your code.
Although this solution works, the idea behind using the same counter, $i, to extract a value from both arrays is brittle. For example, you'll get an Undefined offset if the first array has 5 grades instead of 4. If you take a step back and explain your problem in the larger context, perhaps we can provide a better solution. I get the sneaking suspicion you're asking an XY Problem.
http://sandbox.onlinephpfunctions.com/code/bb4f492c183fcde1cf4edd50de7ceebf19fe343a
<?php
$gradeList1 = ['grade' => [1,2,3,4]];
$gradeList2 = ['grade' => [1,2,3,4]];
$result = [];
for ($i = 0; $i < count($gradeList1['grade']); $i++) {
$first = $gradeList1['grade'][$i];
$second = $gradeList2['grade'][$i];
$result['show_result'][] = (int)$first + (int)$second;
}
var_dump($result);
I have 4 variables and each of those have an integer assigned to them. Could anybody please let me know how I can get the name of the variable which has the second smallest value?
Thanks.
Use compact to set the variables to one array, sort the array, then use array slice to get the second value.
Then optionally echo the key of the second value.
$a = 2;
$b = 7;
$c = 6;
$d = 1;
$arr = compact('a', 'b', 'c', 'd');
asort($arr);
$second = array_slice($arr,1,1);
Echo "variable name " . Key($second) ."\n";
Echo "value " . ${key($second)};
https://3v4l.org/SVdCq
Updated the code with how to access the original variable from the array
Unless you have a structured way of naming your variables eg prefix_x there is no real way.
Recommended way is using an array like this:
$array = array(
"a" => 3,
"b" => 2,
"c" => 1,
"d" => 6
);
// Sort the array descending but keep the keys.
// http://php.net/manual/en/function.asort.php.
asort($array);
// Fetch the keys and get the second item (index 1).
// This is the key you are looking for per your question.
$second_key = array_keys($array)[1];
// Dumping the result to show it's the second lowest value.
var_dump($array[$second_key]); // int(2).
To be more in line with your question you can create your array like this.
$array = array();
$array['variable_one'] = $variable_one;
$array['some_random_var'] = $some_random_var;
$array['foo'] = $foo;
$array['bar']= $bar;
// Same code as above here.
Instead of using 4 variables for 4 integer values, you can use an array to store these values. Sort the array and print the second index of the array i.e. 1.
<?php
$x = array(2,3,1,6);
$i = 0, $j = 0, $temp = 0;
for($i = 0; $i < 4; $i++){
for($j=0; $j < 4 - $i; j++){
if($x[$j] > $x[$j+1]){
$temp = $x[$j];
$x[$j] = $x[$j+1];
$x[$j+1] = $temp;
}
}
}
for($j = 0; $j < 4; $j++){
echo $x[$j];
}
echo $x[1];
?>
First you need to have all Variables in an Array. You can do this this way:
$array = array(
'a' => 3,
'b' => 6,
'c' => 2,
'd' => 1
);
or this way:
$array['a'] = 3;
$array['b'] = 6;
// etc
Then you need to sort the Items with natsort() to receive a natural Sorting.
natsort($array);
Then you flip the Array-Keys with the Values (In Case you want the Value, skip this Line)
$array = array_flip($array);
After this you jump to the next Item in the Array (Position 1) by using next();
echo next($array);
Makes in Total a pretty short Script:
$array = array(
'a' => 3,
'b' => 6,
'c' => 2,
'd' => 1
);
natsort($array);
$array = array_flip($array);
echo next($array);
I'm trying to find out wich variable is bigger (those are all integers):
<?php
$ectoA=3;
$ectoB=5;
$mesoA=0;
$mesoB=4;
$endoA=11;
$endoB=11;
echo max($ectoA,$ectoB,$mesoA,$mesoB,$endoA,$endoB);
I tried with max but it gives the value and not the $varName.
I want to get the name of the variable and if there are two that are equal I need both.
Thanks for the help.
As suggested i tried this and worked but still got to know if I have two MAX values I need to do something else...
$confronto = [
'ectoA' => $ectoA,
'ectoB' => $ectoB,
'endoA' => $endoA,
'endoB' => $endoB,
'mesoA' => $mesoA,
'mesoB' => $mesoB,
];
$result= array_keys($confronto,max($confronto));
$neurotipo = $result[0];
echo $neurotipo;
I want endoA and endoB to be identified...
You can define an array instead, or compact your variables into an array:
//$array = array('ectoA'=>3,'ectoB'=>5,'mesoA'=>0,'mesoB'=>4,'endoA'=>11,'endoB'=>11);
$array = compact('ectoA','ectoB','mesoA','mesoB','endoA','endoB');
$result = array_keys($array, max($array));
Then compute the max() of that array and use array_keys() to search for the max number and return the keys.
print_r($result);
Yields:
Array
(
[0] => endoA
[1] => endoB
)
I would definitely recommend using an array. Then you can do something like this:
$my_array = array(3, 5, 0, 4, 11, 11);
$maxIndex = 0;
for($i = 1; $i < count($my_array); $i++) {
if($my_array[$i] > $my_array[$maxIndex])
$maxIndex = $i;
}
Another option with array keys would be:
$my_array = array("ectoA" => 3, "ectoB" => 5, "mesoA" => 0, "mesoB" => 4, "endoA" => 11, "endoB" => 11);
$maxIndex = "ectoA";
while($c = current($my_array)) {
$key = key($my_array);
if($my_array[$key] > $my_array[$maxIndex])
$maxIndex = $key;
next($my_array);
}
Note: Code not tested, but should be the gist of what needs to be done
use the array like this
<?php
$value= array (
"ectoA" =>3,
"ectoB"=>5,
"mesoA"=>0,
"mesoB"=>4,
"endoA"=>11,
"endoB"=>11);
$result= array_keys($value,max($values))
print_r($result);
?>
As per the documentation, Since the two values are equal, the order they are provided determines the result $endoA is the biggest here.
But I am not sure your intention is to find the biggest value or which variable is the highest
Your code seems to be a working one.
But it would print for you the value of the maximum number, not the name of the variable.
To have the name of the variable at the end you should add some additional code like:
$max = (max($ectoA,$ectoB,$mesoA,$mesoB,$endoA,$endoB);
if($max == $ectoA) echo "ectoA";
if($max == $ectoB) echo "ectoB";
// ... same goes for other variables
But working with an array would be the most proper solution.
Sorry for my bad English and thanks for your help in advance! I have kind of a tricky problem I've encountered while coding. Here's the point:
I need a script that essentially extracts the 5 max values of 5 arrays, that are "mixed", i.e. they contain "recurrent" values. Here is an example:
array1(a, b)
array2(a, c, d, e, g)
array3(b, d, g, h)
array4(e, t, z)
array5(b, c, d, k)
The 2 essential requests are:
1) the sum of those 5 arrays (array1+array2+array3...) MUST be the highest possible...
2) ...without repeat ANY value previously used** (e.g. if in array1 the top value was "b", this cannot be re-used as max value in arrays 3 or 5).
Currently I have this...:
$group1 = array(a, b);
$group = array(a, b, c, d);
$max1a = max(group1);
$max2a = max(group2) unset($max1a);
$sum1 = $max1a + $max2a;
$max2b = max(group2);
$max1b = max(group1)
unset($max2b);
$sum2 = $max1b + $max2b;
if($sum1 > $sum2) {
echo $sum1
} else {
echo $sum2
}
... but it's kinda impossible to use this code with 5 arrays, because I should compare 5! (120...!!!) combinations in order to find the max sum value.
I know the problem is quite difficult to explain and to solve, but I really need your help and I hope you can save me!!!
Cheers
I'm adding this as another answer to leave the previous one intact for someone coming across this looking for that variation on this behaviour.
Given the 2 arrays:
$array1 = array(30, 29, 20);
$array2 = array(30, 20, 10);
The maximum sum using one element from each is 59 - this is dramatically different to my previous approach (and the answers' of others) which took the max element of the first array and then the highest element of the next array that is not equal to any previously used value - this would give 50 instead.
The code you want is this:
$mainArray = array();
$mainArray[] = array(30, 29, 20);
$mainArray[] = array(30, 20, 10);
$tempArray = array();
$newArray = array();
foreach($mainArray as $innerArray) {
$newArray = array();
if (count($tempArray) == 0) {
foreach ($innerArray as $value) {
$newArray[] = array('total' => $value, 'used' => array($value));
}
}
else {
foreach ($tempArray as $key => $innerTempArray) {
$placed = FALSE;
foreach ($innerArray as $value) {
if (!(in_array($value, $innerTempArray['used']))) {
$newArray[] = array('total' => $tempArray[$key]['total'] + $value, 'used' => $tempArray[$key]['used']);
$newArray[count($newArray) - 1]['used'][] = $value;
$placed = TRUE;
}
}
if (!($placed)) {
echo "An array had no elements that had not already been used";
die();
}
}
}
$tempArray = $newArray;
}
$total = 0;
if (count($newArray) == 0) {
echo "No data passed";
die();
}
else {
$total = $newArray[0]['total'];
}
for ($i = 0; $i < count($newArray); $i++) {
if ($newArray[$i]['total'] > $total) {
$total = $newArray[$i]['total'];
}
}
var_dump($total);
EDIT - Do not repeat used variables (but repeated values are ok):
Let
//$a = 30, $b = 30, $c = 25, $d = 20, $e = 19
$array1 = array($a, $c, $d);
$array2 = array($b, $d, $e);
We want to choose $a from $array1 and $b from $array2 as these give the largest sum - although they're values are the same that is allowed because we only care if the names of the variables saved to that place are the same.
With the arrays in the above format there is no way of achieving the desired behaviour - the arrays do not know what the name of the variable who's value was assigned to their elements, only it's value. Therefore we must change the first part of the original answer to:
$mainArray[] = array('a', 'c', 'd');
$mainArray[] = array('b', 'd', 'e');
and also have either the of the following before the first foreach loop (to declare $a, $b, $c, $d, $e)
//either
extract(array(
'a' => 30,
'b' => 30,
'c' => 25,
'd' => 20,
'e' => 19
));
//or
$a = 30; $b = 30; $c = 25; $d = 20; $e = 19;
The above both do exactly the same thing, I just prefer the first for neatness.
Then replace the line below
$newArray[] = array('total' => $value, 'used' => array($value));
with
$newArray[] = array('total' => ${$value}, 'used' => array($value));
The change is curly brackets around the first $value because that is then evaluated to get the variable name to use (like below example):
$test = 'hello';
$var = 'test';
echo ${$var}; //prints 'hello'
A similar change replaces
$newArray[] = array('total' => $tempArray[$key]['total'] + $value, 'used' => $tempArray[$key]['used']);
with
$newArray[] = array('total' => $tempArray[$key]['total'] + ${$value}, 'used' => $tempArray[$key]['used']);
Now the code will function as wanted :)
If you are dynamically building the arrays you are comparing and can't build the array of strings instead of variables then there is no way to do it. You would need some way of extracting "$a" or "a" from $a = 30, which PHP is not meant to do (there are hacks but they are complicated and only work in certain situations (google "get variable name as string in php" to see what I mean)
If by the top value you mean the first alphabetically then the following would work:
$array1 = array('a', 'b');
$array2 = array('a', 'c', 'd', 'e', 'g');
$array3 = array('b', 'd', 'g', 'h');
$array4 = array('e', 't', 'z');
$array5 = array('b', 'c', 'd', 'k');
$mainArray = array($array1, $array2, $array3, $array4, $array5);
foreach ($mainArray as $key => $value) {
sort($mainArray[$key]);
}
$resultArray = array();
foreach($maniArray as $key1 => $value1) {
$placed = FALSE;
foreach ($value1 as $value2) {
if (!(in_array($value2, $resultArray))) {
$resultArray[] = $value2;
$placed = TRUE;
break;
}
}
if (!($placed)) {
echo "All the values in the " . ($key + 1) . "th array are already max values in other arrays";
die();
}
}
var_dump($resultArray);
I'm not sure, of i really understood your problem correctly, these are my assumptions:
You have five arrays containing numbers
These numbers can occur multiple times across the arrays
You want to find the highest possible sum of elements across your arrays
The sum uses one single value of each array
But the sum must not use the same number twice
Is that correct?
If Yes, then:
The highest possible sum across all arrays is always the sum of the largest elements. If you do not want to use the same number twice, you can just get the maximum from the first array, remove it from all the others and then sum up all the remaining maxima.
Like so:
$arrays = array();
$arrays[] = array(1, 2);
$arrays[] = array(1, 3, 4, 5, 7);
$arrays[] = array(2, 4, 7, 8);
$arrays[] = array(5, 20, 26);
$arrays[] = array(2, 3, 4, 11);
for($i=0, $n=count($arrays); $i<$n; $i++) {
if($i===0) {
$a1max = max($arrays[$i]);
$sum = $a1max;
} else {
$duplicate_pos = array_search($a1max, $arrays[$i]);
if($duplicate_pos !== FALSE) {
unset($arrays[$i][$duplicate_pos]);
}
$sum += max($arrays[$i]);
}
}
echo "sum: " . $sum . "\n";
Assuming you have grouped together all your values in one array like this,
$array = array(
array(1,2,3),
array(1,2,3,4),
array(1,2,3,4,5,6),
array(1,2,3,4,5,6),
array(1,2,3,4,5,6,7)
);
Loop through $array, and get the highest value which has not been used previously,
$max = array();
foreach($array as $value)
$max[] = max(array_diff($value, $max));
Calculate the sum of all values with array_sum(),
echo "The maximal sum is: ".array_sum($max);