Reputation: 49
I have an array called $products
.
If I perform a print_r
of this array, I get the following output:
Array
(
[0] => Array
(
[0] => 2
[counter] => 2
[1] => Oranges
[item] => Oranges
)
[1] => Array
(
[0] => 3
[counter] => 3
[1] => Bananas
[item] => Bananas
)
[2] => Array
(
[0] => 1
[counter] => 1
[1] => Apples
[item] => Apples
)
[3] => Array
(
[0] => 1
[counter] => 1
[1] => Pears
[item] => Pears
)
)
I want to be able to list the item name which has the lowest 'counter'
value, and if there are duplicate lowest counter values (like in the example above, apples and pears), then for only one to be chosen at random (must be randomly chosen).
Is anyone able to help me with this? Unfortunately I've not been able to find a suitable solution so far. Thanks in advance!
Upvotes: 2
Views: 2372
Reputation: 7446
I would personally use usort in such a case, so that if two elements have the same counter you can foresee that later.
Besides, you can easily solve that issue from your mysql query, but here is how I would do this:
<?php
$products = array(
array(
"counter" => 2,
"item" => "Oranges"
),
array(
"counter" => 3,
"item" => "Bananas"
),
array(
"counter" => 1,
"item" => "Apples"
),
array(
"counter" => 1,
"item" => "Pears"
)
);
usort($products, function($previous, $next) {
return $previous["counter"] > $next["counter"] ? 1 : -1;
});
echo "Lowest counter is: {$products[0]['item']}";
?>
Explanation:
usort($products, function($previous, $next) {
return $previous["counter"] > $next["counter"] ? 1 : -1;
});
usort takes $products (the array) as the array to fetch and loops two items at a time (previous and next), the return statements check whether the previous element's counter is higher than the next one, if so, it puts it after it, else before it.
In the end, you will have the array elements sorted from the lowest counter one to the highest one.
I would suggest you, also, to later get the ones that have the same counter value if, such in this case, you have two elements which both are low, like this:
$products = array(
array(
"counter" => 2,
"item" => "Oranges"
),
array(
"counter" => 3,
"item" => "Bananas"
),
array(
"counter" => 1,
"item" => "Apples"
),
array(
"counter" => 1,
"item" => "Pears"
)
);
usort($products, function($previous, $next) {
return $previous["counter"] > $next["counter"] ? 1 : -1;
});
$lowest = $products[0]["counter"];
$filtered = array_filter($products, function($element) use ($lowest) {
return $element["counter"] === $lowest;
});
echo $filtered[array_rand($filtered, 1)]["item"];
working code:
Upvotes: 2
Reputation: 2941
<?php
$products;//What ever you have assigned to this...
$size = count($products); // size of products array
$tmp = PHP_INT_MAX; // Set this to the highest possible counter value.
for($i = 0; $i < $size; $i++)
{
//If a new lowest counter has been found empty array and append this value
if($products[$i]["counter"] < $tmp)
{
$lowest = array();
$lowest[0] = $products[$i]["item"];
$tmp = $products[$i]["counter"];
}
//If counter is equally low append value
if($products[$i]["counter"] == $tmp)
{
$lowest[] = $products[$i]["item"];
}
}
echo array_rand($lowest);
?>
EDIT: Updated the code.
EDIT2: Addes Explanation below the code
This code works as follows:
The loop circels through the entire array. Which each step it checks whether the counter is lower then the one previously stored, initially the highest possible int value. If it is, the array with all wanted values is completely reset.
Next the loop checks whether the lowest value is the same as the previously stored "lowest" value. If so the item name is added to the array. In this way syou can collect all item names with the lowest value (one or more item names) in one array. If one smaller value occurs all item names before are not longer interesting and hence can be deleted. Once the loop has finished the function array_rand()
outputs one random value, as you want it to. This is outputted as a string but can also be assigned to a variable.
I hope this helps to understand my code.
Upvotes: 1
Reputation: 2847
This will take your $products
and loop over each of them. Using the first element to set your currentLowest. If the value is a match it will add it to an array. If something less is found it will replace the currentLowest and remove the array values adding that value to a new one. At the end array_rand will give you a random index that you can use to access the lowValues.
<?php
//products is defined somewhere
$lowValues = array();
//Just to get it started
$currentLowest = $products[0]["counter"];
foreach($products as $product){
if($product["counter"] == $currentLowest){
//When Equal just add it
$lowValues[] = $product["item"];
} elseif($product["counter"] < $currentLowest) {
//When lower set as lowest
$currentLowest = $product["counter"];
//Remove all old values
unset($lowValues);
//Add this to the low values
$lowValues[] = $product["item"];
} else {
//Nothing to do here...
}
}
//array_rand is an index.
echo $lowValues[array_rand($lowest)];
?>
Upvotes: 0
Reputation: 204
You want to get random minimum array from $data. For this you should do some following code.
$data[]=array
(
'0' => 2,
'counter' => 2,
'1' => 'Oranges',
'item' => 'Oranges'
);
$data[]=array
(
'0' => 3,
'counter' => 3,
'1' => 'Bananas',
'item' => 'Bananas'
);
$data[]=array
(
'0' => 1,
'counter' => 1,
'1' => 'Apples',
'item' => 'Apples'
);
$data[]=array
(
'0' => 1,
'counter' => 1,
'1' => 'Pears',
'item' => 'Pears'
);
$min=min(array_column($data, 'counter'));
$minarray=array();
foreach($data as $key=>$value) {
if($value['counter']==$min){
array_push($minarray,$value);
}
}
$rand_keys =array_rand($minarray);
echo"<pre>";
print_r($minarray[$rand_keys]);
Try this code on http://phpfiddle.org/ for online test. I hope you will get solution.
Upvotes: 0
Reputation: 2304
How about simplifying with the use of usort?
function compare_products($product1, $product2){
if($product1['counter'] == $product2['counter']){
return rand(0,1) ? 1 : -1//if it is the same then it is random
}
return $product1['counter'] > $product2['counter'];// if not it sorts the array
}
$products = ...;//your array
usort($products, "compare_products");
Then to get the lowest just do
echo $products[0];
Working example here (Idone) I simplified your array for the example
Upvotes: 2