I am trying to output a ranking by lowest number first for a particular field (OurPrice) based on numeric values.
var_dump Result
$myarray = array_filter($rankresult);
natsort($myarray);
array(6) {
["Comp7"]=> string(3) "189"
["OurPrice"]=> string(3) "189"
["Comp9"]=> string(6) "198.99"
["Comp6"]=> string(3) "208"
["Comp3"]=> string(6) "226.97"
["Comp4"]=> string(3) "274"
}
You will notice that there are 6 total in the count and two of which are the same number, therefore it would equal the same rank (ie. Comp7 and OurPrice are both ranked 1 of 6).
Desired Output:
Our Price Rank = 1 of 6
try with this code
$newarray = (array_unique(array_values($myarray)));
$rank = array_search($myarray['OurPrice'],$newarray)+1;
$count = count($myarray));
echo "Our Price Rank" . $rank . " of " . $count"
Assuming you have already sorted the values (which it appears you have), you could simply tell them the index at which the "OurProduct" key exists.
$keys = array_keys( $array );
$rank = array_search( "OurPrice", $keys );
printf( "We rank %d of %d", ++$rank, count($keys) );
Try it online: http://codepad.org/qIwTGBzG
Related
I'm trying to sum values from the array from certain ranges provided by another array.
I've tried with this function
function sumArray($array, $min, $max) {
$sum = 0;
foreach ($array as $k => $v) {
if ($k >= $min && $k <= $max) {
$sum += $v;
}
}
return $sum;
}
and this works if i hardcode numbers of course, but i can't figure out how to make this work in a loop
So I have this dates array
array(3) {
["June"]=> int(4)
["July"]=> int(31)
["August"]=> int(29)
}
and i have this daily_values array
array(64) {
[0]=> int(8)
[1]=> int(6)
[2]=> int(10)
[3]=> int(15)
[4]=> int(10)
[5]=> int(9)
[6]=> int(9)
.
.
.
[63] => int(10)
Now what I want to do here is:
based on how many entries are in for example June which is 4 in this case I want to get the sum of values in daily_values array like this:
first loop iteration will sum values in daily_values array from 0 to 3, the second loop iteration will sum values from 4 to 34 and third loop iteration will sum values from 35 to 63 and so on and so on.
So the final thing I want from all this is to have an array which will be like this
["sum of 0,3", "sum of 4,34", "sum of 35,63"]
Just a note here, this array is much bigger, but I cut it short just for question purposes.
I tried to understand your question and here is what I think you are trying to achieve.
I created a similar test and it works fine. Hope it helps you in someway.
<?php
$june = [1,1,1,1];
$july = [1,1];
$august = [1,1,1,1];
$months = array(
'June' => $june,
'July' => $july,
'August' => $august,
);
$daily = [1,1,1,1,5,5,10,10,10,10,2,2,2,2,2];
$sum_arr = array();
$i = 0;
foreach($months as $key=>$month){
$month_count = $month;
$month_sum = 0;
while($month_count > 0){
$month_sum += $daily[$i];
$i++;
$month_count--;
}
$sum_arr[$key] = $month_sum;
}
echo '<pre>';
print_r($sum_arr);
?>
Its my first time working with multidimensional arrays in php. I need to change the second number in each sub array.
What I want is to check if the Id in the array matches the Id from the database. When the two match I want to change the 2nd entry in the sub array by adding a number to it. If the Id from the query does not match anything in the list I want a new sub array to be pushed to the end of the array with the values of Id and points_description.
Also, if its helpful, my program right now does find the matches. The only thing is, it does not update the 2D array.
$array = array(array());
while ($row_description = mysqli_fetch_array($query_description)) {
$check = 1;
$is_match = 0;
foreach ($array as $i) {
foreach ($i as $value) {
if ($check == 1) {
if ($row_description['Id'] == $value) {
//$array[$i] += $points_description;
$is_match = 1;
}
}
$check++;
$check %= 2; //toggle between check and points
}
}
if ($is_match == 0) {
array_push($array, array($row_description['Id'], $points_description));
}
}
I feel like Im doing this so wrong. I just want to go through my 2D array and change every second value. The expected output should be a print out of all the Ids and their corresponding point value
I hope this is helpful enough.
Example: $row_description['Id'] = 2 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1))
if $row_description['Id'] = 3 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1),array(3,3))
By default PHP will copy an array when you use it in a foreach.
To prevent PHP from creating this copy you need to use to reference the value with &
Simple example :
<?php
$arrFoo = [1, 2, 3, 4, 5,];
$arrBar = [3, 6, 9,];
Default PHP behavior : Make a copy
foreach($arrFoo as $value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
*/
ByReference : Don't create the copy :
foreach($arrFoo as &$value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(162)
[1]=>
int(324)
[2]=>
int(486)
[3]=>
int(648)
[4]=>
&int(810)
}
*/
Hi I am trying to count the number of duplicate values in a associative array that looks like this:
array(3) { [0]=> array(3) { ["Title"]=> string(25) "hello"
["Price"]=> int(50)
["Count"]=> int(1) }
[1]=> array(3) { ["Title"]=> string(35) "world"
["Price"]=> int(50)
["Count"]=> int(1) }
[2]=> array(3) { ["Title"]=> string(25) "hello"
["Price"]=> int(50)
["Count"]=> int(1) } }
As you can see here there is a duplicate value in the "Title" lable I want to count them and add one to the "Count" part. I started to do something like this:
$prodArray = array();
// Add the values to the array if it's the first time it occurs.
if (!in_array($row['prodTitle'], $prodArray["Title"]))
{
array_push($prodArray,
array( Title => $row['prodTitle'],
Price => $row['prodPrice'],
Count => 1)
);
}
else
{
//Add one to the count for the current item.
}
the thing is I can't access the "Title" element in the array through the in_array function. Any suggestions are welcome.
If you want to detect dups in an array that you are creating, something like this avoid having to go through the array multiple times:
$arr=array();
while($row = mysql_fetch_array($result)) {
$arr[$row['prodTitle']] = isset($arr[$row['prodTitle']])
? $arr[$row['prodTitle']] +1
: 0;
}
$dups = array_keys(array_filter($arr)); //any key => 0 will be filtred out
If you want to just get the dups directly by SQL, have a look at this:
Your current query--
SELECT prodTitle
FROM product
WHERE prodTitle != '{$keyword}'
AND creditCard IN( SELECT creditCard FROM product WHERE prodTitle ='{$keyword}');
which given data like this
prod cc
A 1
A 2
A 3
A 1
A 1
B 15
B 1
B 2
B 21
C 10
C 1
returns this set (with $keyword=='A'):
prod
B
B
C
An aggregate query that returns only records where credit cards used on non-X were also used on X at least twice --
SELECT p1.prodTitle, COUNT(p2.creditCard) AS numrecords
FROM product p1
JOIN product p2
ON (p1.creditCard = p2.creditCard)
WHERE p1.prodTitle != '{$keyword}'
AND p2.prodTitle = '{$keyword}'
GROUP BY p1.prodTitle
HAVING COUNT(p2.creditCard) > 1;
given the same data, returns this set:
prod num
B 2
Doing an aggregate query avoids all the messing about with loops. Here's a link to the MySQL list of aggregate functions.
Okey so I found my solution and I made it look something like this probably not he most efficient way but it works:
$prodArray = array();
$ar = array();
$query ="THE QUERY";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result))
{
array_push($ar, $row['prodTitle']);
}
function findDuplicates($data,$dupval) {
$nb= 0;
foreach($data as $key => $val)
if ($val==$dupval) $nb++;
return $nb;
}
$uniarr = array_unique($ar);
//Will run the function findDuplicates for each unique title in the array
for ($i = 0; $i < sizeof($uniarr); $i++)
{
$count = findDuplicates($ar, $uniarr[$i]);
array_push($prodArray, array( Title => $uniarr[$i], Count => $count));
}
//Displays 2 of the results in the array
for ($c = 0; $c < 2; $c++)
{
echo "The title:".$prodArray[$c]["Title"]." And the amount:".$prodArray[$c]["Count"];
echo "<br />";
}
So that's pretty much it feel free to post your comments on this and if you have any improvements feel free to post them.
I need some help/direction in setting up a PHP script to randomly pair up items in an array.
The items should be randomly paired up each time.
The items should not match themselves ( item1-1 should not pair up with item1-1 )
Most of the items have a mate (ie. item1-1 and item1-2). The items should not be paired with their mate.
I've been playing around with the second script in this post but, I haven't been able to make any progress. Any help is appreciated.
Very simple approach, but hopefully helpful to you:
(mates, if grouped in an array (e.g. array('a1', 'a2')), will not be paired.)
function matchUp($array) {
$result = array();
while($el = array_pop($array)) {
shuffle($array);
if (sizeof($array) > 0) {
$candidate = array_pop($array);
$result[] = array(
array_pop($el),
array_pop($candidate)
);
if (sizeof($el) > 0) {
$array[] = $el;
}
if (sizeof($candidate) > 0) {
$array[] = $candidate;
}
}
else {
$result[] = array(array_pop($el));
}
}
return $result;
}
$array = array(
array('a1', 'a2'),
array('b1', 'b2'),
array('c1'),
array('d1'),
array('e1', 'e2'),
array('f1'),
array('g1', 'g2'),
);
Update:
foreach(matchUp($array) as $pair) {
list($a, $b) = $pair + array(null, null);
echo '<div style="border: solid 1px #000000;">' . $a . ' + ' . $b . '</div>';
}
With the randomness, there is no guarantee that a full correct solution will be reached.
Certain problem sets are more likely to be solved than others. Some will be impossible.
You can configure how many times it will try to achieve a good solution. After the specified number of tries it will return the best solution it could find.
function pairUp (array $subjectArray) {
// Config options
$tries = 50;
// Variables
$bestPaired = array();
$bestUnpaired = array();
for($try = 1; $try <= 50; $try++) {
$paired = array();
$unpaired = array();
$toBePaired = $subjectArray;
foreach($subjectArray as $subjectIndex => $subjectValue) {
// Create array without $thisValue anywhere, from the unpaired items
$cleanArray = array();
foreach($toBePaired as $index => $value) {
if($value != $subjectValue) {
array_push($cleanArray, array(
'index' => $index,
'value' => $value
));
}
}
sort($cleanArray); // reset indexes in array
// See if we have any different values left to match
if(count($cleanArray) == 0) {
array_push($unpaired, $subjectValue);
continue;
}
// Get a random item from the clean array
$randomIndex = rand(0,count($cleanArray)-1);
// Store this pair
$paired[$subjectIndex] = $subjectValue . '-' . $cleanArray[$randomIndex]['value'];
// This item has been paired, remove it from unpairedItems
unset($toBePaired[$cleanArray[$randomIndex]['index']]);
sort($toBePaired);
}
// Decide if this is our best try
if(count($paired) > count($bestPaired)) {
$bestPaired = $paired;
$bestUnpaired = $unpaired;
}
// If we had no failures, this was a perfect try - finish
if(count($unpaired) == 0) { $break; }
}
// We're done, send our array of pairs back.
return array(
'paired' => $bestPaired,
'unpaired' => $bestUnpaired
);
}
var_dump(pairUp(array('a','b','c','d','e','a','b','c','d','e')));
/*
Example output:
array(2) {
["paired"]=>
array(10) {
[0]=>
string(3) "a-b"
[1]=>
string(3) "b-c"
[2]=>
string(3) "c-d"
[3]=>
string(3) "d-e"
[4]=>
string(3) "e-a"
[5]=>
string(3) "a-b"
[6]=>
string(3) "b-e"
[7]=>
string(3) "c-d"
[8]=>
string(3) "d-c"
[9]=>
string(3) "e-a"
}
["unpaired"]=>
array(0) {
}
}
*/
Case 1: if all elements had a mate
If all elements had a mate, the following solution would work, although I don't know if it would be perfectly random (as in, all possible outputs having the same probability):
Shuffle the list of elements, keeping mates together
original list = (a1,a2),(b1,b2),(c1,c2),(d1,d2)
shuffled = (c1,c2),(d1,d2),(a1,a2),(b1,b2)
Shift the second mate to the right. The matches have been formed.
shifted = (c1,b2),(d1,c2),(a1,d2),(b1,a2)
(Edit1: if applied exactly as described, there is no way a1 ends up matched with b1. So, before shifting, you may want to throw a coin for each pair of mates to decide whether they should change their order or not.)
Case 2: if only some elements have a mate
Since in your question only some elements will have a mate, I guess one could come up with the following:
Arbitrarily pair up those elements who don't have a mate. There should be an even number of such elements. Otherwise, the total number of elements would be odd, so no matching could be done in the first place.
original list = (a1,a2),(b1,b2),c1,d1,e1,f1 // c1,d1,e1 and f1 don't have mates
list2 = (a1,a2),(b1,b2),(c1,d1),(e1,f1) // pair them up
Shuffle and shift as in case 1 to form the matches.
shuffled = (e1,f1),(a1,a2),(c1,d1),(b1,b2)
shifted = (e1,b2),(a1,f1),(c1,a2),(b1,d1)
Again, I don't know if this is perfectly random, but I think it should work.
(Edit2: simplified the solution)
(Edit3: if the total number of elements is odd, someone will be left without a match, so pick an element randomly at the beginning to leave it out and then apply the algorithm above).
update
I'm new to PHP development: I looked on the PHP website for a function - array_slice. I read and looked at the example but I don't understand it. Can someone explain this in clear words for me?
I think it works as follow?
$example = array(1,2,3,4,5,6,7,8,9);
$offset = 2;
$length = 5;
$newArray = array_slice($example, offset, length);
the result of $newArray is: $newArray(3,4,5,6,7);
In addition to stefgosselin's answer that has some mistakes: Lets start with his array:
$input = array(1,2,3);
This contains:
array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
Then you do array_slice:
var_dump(array_slice($input, 1));
The function will return the values after the first element (thats what the second argument, the offset means). But notice the keys!
array(2) {
[0]=> int(2)
[1]=> int(3)
}
Keep in mind that keys aren't preserved, until you pass true for the fourth preserve_keys parameter. Also because there is another length parameter before this, you have to pass NULL if you want to return everything after the offset, but with the keys preserved.
var_dump(array_slice($input, 1, NULL, true));
That will return what stefgosselin (incorrectly) wrote initially.
array(2) {
[1]=> int(2)
[2]=> int(3)
}
This function returns a subset of the array. To understand the example on the man page you have to understand array keys start at 0, ie
$array_slice = $array(1,2,3);
The above contains this:
$array[0] = 1,
$array[1] = 2,
$array[2] = 3
So, array_slice(1) of $array_sliced would return:
$arraysliced = array_slice($array_slice, 1);
$arraysliced[1] = 2;
$arraysliced[2] = 3;
It returns the part of your input array that starts at your defined offset, of the your defined length.
Think of it this way:
$output = array();
for ($i = 0; $i++; $i < count($input)) {
if ($i < $start)
continue;
if ($i > $start + $length)
break;
$output[] = $input[$i];
}
Basically its an skip and take operation. Skip meaning to jump to that element. Take meaning how many.
PHP has a built - in function, array_slice() , that you can use to extract a range of elements from an
array. To use it, pass it the array to extract the slice from, followed by the position of the first element in
the range (counting from zero), followed by the number of elements to extract. The function returns a new
array containing copies of the elements you extracted (it doesn ’ t touch the original array). For example:
$authors = array( “Steinbeck”,
“Kafka”, “Tolkien”, “Dickens” );
$authorsSlice = array_slice(
$authors, 1, 2 ); // Displays “Array
( [0] = > Kafka [1] = > Tolkien )”
print_r( $authorsSlice );
By the way, if you leave out the third argument to array_slice() , the function extracts all elements
from the start position to the end of the array:
$authors = array( “Steinbeck”, “Kafka”, “Tolkien”, “Dickens” );
$authorsSlice = array_slice( $authors, 1 );
// Displays “Array ( [0] = > Kafka [1] = > Tolkien [2] = > Dickens )”;
print_r( $authorsSlice );
Earlier you learned that array_slice() doesn ’ t preserve the indices of elements taken from an indexed
array. If you want to preserve the indices, you can pass a fourth argument, true , to array_slice() :
$authors = array( “Steinbeck”, “Kafka”, “Tolkien”, “Dickens” );
// Displays “Array ( [0] = > Tolkien [1] = > Dickens )”;
print_r( array_slice( $authors, 2, 2 ) );
// Displays “Array ( [2] = > Tolkien [3] = > Dickens )”;
print_r( array_slice( $authors, 2, 2, true ) );