how to get array random from object? - php

I tried to make array from random item object to get 2 items. I used array_rand() but the output is array_rand() expects parameter 1 to be array, integer given and Trying to get property of non-object
My code is for get random item is :
$k=2;
$centroid = array();
for($i=0; $i<$k; $i++){
$centroid[] = new DataSet($table[array_rand($i)]->sig_class_id,$table[array_rand($i)]->sig_priority);
}
Get data from
$query = mysqli_query($conn,"SELECT sig_class_id, sig_priority FROM coba");
$table=array();
while ($row = mysqli_fetch_object($query)) {
$table[] = new DataSet($row->sig_class_id, $row->sig_priority);
}
and class DataSet is
class DataSet{
public $sig_class_id;
public $sig_priority;
function __construct($sig_class_id, $sig_priority){
$this->sig_class_id = $sig_class_id;
$this->sig_priority = $sig_priority;
}
}
any thought?

I think you are in wrong logic. Instead, you should get a random number and get random number related array. Try below code!
$random = 0;
$centroid = array();
for($i=0; $i=2; $i++){
$random = rand();
$centroid[] = new DataSet($table[$random]->sig_class_id,$table[$random]->sig_priority);
}
== Edit 1 ==
Tip 1 : You can also use mt_rand() function produces a better random value, and is 4 times faster than rand().
Tip 2 : If you want a random integer between 10 and 100 (inclusive), use rand (10,100).

Related

Is there a faster way than array_diff in PHP

I have a set of numbers from MySQL within the range 1000 0000 (8 digits) to 9 999 999 999 (10 digits). It's supposed to be consecutive, but there are missing numbers. I need to know which numbers are missing.
The range is huge. At first I was going to use PHP to do this:
//MySqli Select Query
$results = $mysqli->query("SELECT `OCLC Number` FROM `MARC Records by Number`");
$n_array = array();
while($row = $results->fetch_assoc()) {
$n_array[] = $row["OCLC Number"];
}
d($n_array);
foreach($n_array as $k => $val) {
print $val . " ";
}
/* 8 digits */
$counter = 10000000;
$master_array = array();
/* 10 digits */
while ($counter <= 9999999999 ) {
$master_array[] = $counter;
$counter++;
d($master_array);
}
d($master_array);
$missing_numbers_ar = array_diff ($master_array, $n_array);
d($missing_numbers_ar);
d() is a custom function akin to var_dump().
However, I just realized it would take tons of time for this to be done. At the 15 minute mark, $master_array is being populated with only 4000 numbers.
How can I do this in a quicker way? MySQL-only or MySQL-and-PHP solutions both welcome. If the optimal solution depends on how many numbers are missing, please let me know how so. Tq.
Your d() probably is the cause of slowness, please remove it, and make small changes in your code
while($row = $results->fetch_assoc()) {
$n_array[$row["OCLC Number"]] = 1;
}
and
$missing_numbers_ar = [];
while ($counter++ <= 9999999999 ) {
if (empty($n_array[$counter])) {
$missing_numbers_ar[] = $counter;
}
}
If the following is still slow I would be surprised. I also just noticed it is similar to #Hieu Vo's answer.
// Make sure the data is returned in order by adding
// an `ORDER BY ...` clause.
$results = $mysqli->query("SELECT `OCLC Number`
FROM `MARC Records by Number`
ORDER BY `OCLC Number`");
$n_array = array();
while($row = $results->fetch_assoc()) {
// Add the "OCLC Number" as a key to the array.
$n_array[$row["OCLC Number"]] = $row["OCLC Number"];
}
// assume the first array key is in fact correct
$i = key($n_array);
// get the last key, also assume it is not missing.
end($n_array);
$max = key($n_array);
// reset the array (should not be needed)
reset($n_array);
do {
if (! $n_array[$i]) {
echo 'Missing key:['.$i.']<br />';
// flush the data to the page as you go.
flush();
}
} while(++$i <= $max);

Find the matched value of an array with a given value

I have an array of value series like:
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
Another value getting from DB like:
$point = $data[‘earned_point’];
I need the highest match from the series. such as I got a value from db (1500) the highest match of the value is 1000 in the series, so I need to get the $series[4] and make it
$reward = $series[4] * 0.1;
I'll run it in a loop to do it for all the values got from DB.
I'm posting alternate code as the accepted answer while is correct can be very inefficient if you are working with a large array.
<?php
function computeReward($series, $point, $percent = 0.1){
arsort($series); // sort the series in reverse so we can pass any array and the highest number will be the first because we are looking for a number lower or equal to our point
foreach($series as $min_point){
if($min_point <= $point){
return $min_point * $percent; // return the min_point * the percentage, this stops the loop there for being more efficient
}
}
}
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
$point = $data['earned_point'];
$reward = computeReward($series, $point);
?>
Do you mean you want to get which highest $series item is equal or less than $point ?
<?php
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
$point = $data['earned_point'];
foreach ($series as $min_point) {
if ($point >= $min_point) {
$matched_min_point = $min_point;
}
}
$reward = $matched_min_point*0.1;
Let me know if this works for you

generate random number from an array

in mock test, i store id of questions in an array and i want when test start then it generate radomly id's from this array. when id is less then 10 then it generate correct number but when it store greater then 10 like 20,21,22.. then it also generate also number form 1-10. i want it generate random number from number which store in this array. thnax..
$ids= array('20','21','22','23','24','25','26','27','28','29','30','31','32',);
$getIds=mysql_query("select * from mock_test_question where status='1' and question_level='FINAL' ") or die(mysql_error());
while($data=mysql_fetch_array($getIds))
{
array_push($ids, $data['id']);
}
print_r($ids);
echo "</br>";
$rand_keys = array_rand($ids,5);
$_SESSION['quesid']=$rand_keys;
print_r($rand_keys);
array_rand returns the KEYS (array positions) not the actual values. To get the values:
echo $ids[$rand_keys];
This should give you a random number
$randomValues = array('20','21','22','23','24','25','26','27','28','29','30','31','32');
$randomValuesIndex = array_rand($randomValues, 1);
$randomValue = $randomValues[$randomValuesIndex];
echo $randomValue."\n";
An example loop that generates random numbers
$randomValues = array('20','21','22','23','24','25','26','27','28','29','30','31','32');
for ($i = 1; $i < 30; $i++)
{
$randomValuesIndex = array_rand($randomValues, 1);
$randomValue = $randomValues[$randomValuesIndex];
echo $randomValue."\n";
}
$count = count($ids) - 1; # note that its -1 because array keys start from 0
echo $ids[rand(0,$count)];
here is a fast way to get random element from array
P.S>
Here is complete code with generate of numbers and usage..
$ids = array();
for($i=20;$i<=32;$i++){ $ids[]=$i; }
$count = count($ids) - 1;
echo $ids[rand(0,$count)];
echo $ids[rand(0,$count)];
echo $ids[rand(0,$count)];

Function generating Unique Random Values Array

As Mysql rand() is time consuming I am using alternate way using Mysql max() and PHP. I wrote this code for fetching random product_id's:
function RandomUniqueArray($min,$max,$limit){
$random_array = array();
if(isset($limit) && is_numeric($limit)){
for($i=0;$i<$limit;){
$rand_val = mt_rand($min, $max);
if(!in_array($rand_val, $random_array)){
$random_array[] = $rand_val;
$i++;
}
}
}
return $random_array;
}
This works fine as I want each time it gives different result set with different unique values but it takes 6.232 micro seconds.
Ohter I got by Google is:
$random_array = array_rand(array_fill($min,$max, true),$limit);
with takes only 0.101 microseconds but its result set is repeated means. Unique values array is fine but whole set is repeated. Why is it so???
I called both of these by one by one as
$random_array = RandomUniqueArray(1,64000,4);
And
$random_array = array_rand(array_fill(1,64000, true),4);
Thank you.
I made a script,that only takes ̣̣̣+- 4.5E-6.
Try it.
function randomValue($min,$max,$limit)
{
$array = Array();
$MAX = mt_rand($min,$max);
for($i = 0;$i < $limit;$i++)
{
$array[$i] = mt_rand($min,$MAX);
while( is_array($array[$i],$array) ) //To check if exist, if. Make new.
{
$array[$i] = mt_rand($min,$MAX);
}
}
return $array;
}

How to configure php's "array_rand" to not give 2 same results on after another?

I use php array_rand to select 1 random record from array, Example:
$style_class = array("st_style1","st_style2","st_style3","st_style4");
$random_class = array_rand($style_class, 1);
$div_class = $style_class[$random_class];
The issue is that sometimes it gives a same record several times, and as I use only 4 records it happens quiet often (using "array_rand" is not neccesary) .
Example:
st_style1,
st_style2,
st_style2,
st_style2,
st_style4,
st_style2 ...
Is there a way to solve this issue, so two same record would not get displayed two times in a row.
For example
st_style2, st_style4, st_style2, st_style1, st_style3, st_style2, st_style1 ...
The simpliest solution is to keep track of the latest one and keep calling random until you get something different. Something like:
$style_class = array("st_style1","st_style2","st_style3","st_style4");
$styles = array()
$lastStyle = -1
for($i = 0; $i < 5; $i++) {
while(1==1) {
$newStyle = array_rand($style_class, 1);
if ($lastStyle != $newStyle) {
$lastStyle = $newStyle;
break;
}
}
$div_class = $style_class[$lastStyle]
$styles[] = $div_class
}
Then use the $styles[] array in order. It should not have any duplicates
Basically same as James J. Regan IV's answer, but using a do-while loop:
Set up the array like this:
$style_class = array("st_style1","st_style2","st_style3","st_style4");
$prev_class = -1;
And then, to obtain a random class:
do {
$random_class = array_rand($style_class, 1);
} while ($random_class == $prev_class);
$div_class = $style_class[$prev_class = $random_class];
Edit: Alternative solution, with no loops:
$style_class = array("st_style1","st_style2","st_style3","st_style4");
$random_class = array_rand($style_class);
To obtain a new random class:
$random_class += rand(1, count($style_class)-1);
$div_class = $style_class[$random_class % count($style_class)];
This works as long as the array keys are consecutive integers starting from zero (as is the case if you define it with array() and don't explicitly specify any keys).
Save the last style in a var, then make a loop till the new style differs from last style. And then you will have a different from the last on every execution.

Categories