Count values in array and calculate top 4 - php

I have CSV list with team names in it (this is one row):
Teams
Red
Green | Red | Yellow
Red
Yellow | Green | Yellow
Red
Green
Yellow | Yellow | Red
Red
Green
Red
Yellow
I need to be able to count each individual color and count top 4
and number of times they appear.
How can I do that? For example if i try using:
$teams = file('count.csv');
$count[] = (array_count_values($colors));
print_r($count);
I get:
Array ( [0] => Array ( [Teams ] => 1
[Red ] => 5 [Green | Red | Yellow ] => 1 [Yellow | Green | Yellow ] => 1 [Green ] => 2 [Yellow | Yellow | Red ] => 1 [Yellow] => 1 ) )
Which is not very useful. And afrewards how could I compare the valies to one another to get top 4?
Any tricks known how to make this happen? Thank you in advance!
OK another try:
$inputfile = 'count.csv';
$inputHandle = fopen($inputfile, "r");
while (($data = fgetcsv($inputHandle, 1024, ",")) !== FALSE) {
$teams = $data[0];
$teams = explode('|', $teams);
}
$count[] = (array_count_values($teams));
print("<pre>".print_r($count, true)."</pre>");
I get
Array
(
[0] => Array
(
[Yellow] => 1
)
)
What am I doing wrong?

If I understand correctly, you've got one row of data, with | as the delimiter.
Here's a very crude quick'n'dirty solution.
What I would do is first use strpos() and substr() to get the colors, and use a switch-case to increment counters for each color. To get the top 4, create an array to hold four strings, insert the first four colors, and then compare the remaining colors to each value in the array, overwriting values in the array if the color you're comparing has a higher count than any value in the array.
This sounds a bit confusing, so let me know if you'd like me to write some sample code demonstrating this.

Related

How to generate a query using an array of delimited columns & values

I have this array:
$filter=['color*black','color*blue','color*red','paint*apex','paint*dalton'];
Each value in $filter has two substrings separated by *. The first substring represents a database table column and the second represents a desired value for that column.
My products table looks like this:
id name color paint
1 p1 black compo
2 p2 red dalton
3 p3 pink apex
4 p4 blue apex
5 p5 cream compo
Using $filter, I need to search the products table and return all rows with a paint value of apex or dalton AND a color value of black, blue, or red.
The desired output is a mysql query that will only return these rows:
id name color paint
2 p2 red dalton
4 p4 blue apex
If You need to construct a query like this SELECT * FROM products WHERE (color IN ('black', 'blue', 'red')) AND (paint IN ('apex', 'dalton')), then the code below might be useful (please, check it here):
$filter = array(
0 => "color*black",
1 => "color*blue",
2 => "color*red",
3 => "paint*apex",
4 => "paint*dalton"
);
$elements = [];
foreach ($filter as $value) {
list($before, $after) = explode('*', $value);
$elements[$before][] = $after;
}
$parts = [];
foreach ($elements as $column => $values) {
$parts[] = "(`$column` IN ('" . implode("', '", $values) . "'))";
}
$query = 'SELECT * FROM `products` WHERE ' . implode(' AND ', $parts);
Running this query against the given table data structure:
id name color paint
1 p1 black compo
2 p2 red dalton
3 p3 pink apex
4 p4 blue apex
5 p5 cream compo
will match the following rows:
2 p2 red dalton
4 p4 blue apex
Here we are using explode, foreach and array_values to achieve desired output.
Try this code snippet here
<?php
$filter = array(
0 => "color*black",
1 => "color*blue",
2 => "color*red",
3 => "paint*apex",
4 => "paint*dalton");
$result=array();
foreach($filter as $value)
{
list($before,$after)=explode("*",$value);
$result["before"][$before]=$before;
$result["after"][$after]=$after;
}
$result["before"]= array_values($result["before"]);
$result["after"]= array_values($result["after"]);
print_r($result);
Output:
Array
(
[before] => Array
(
[0] => color
[1] => paint
)
[after] => Array
(
[0] => black
[1] => blue
[2] => red
[3] => apex
[4] => dalton
)
)

Outputting each value in array

I have this foreach loop nested inside a while loop:
foreach ($_SESSION['arrayPoints'] as $value) {
echo $value;
}
This outputs the all the values stored in the array, 543216 as shown below, but as the foreach loop is in the while loop, 543216 is repeated until there are no more rows:
I need the foreach loop to output each value in the array separately for each row.
So for example (using the image above and the array values of 543216):
I need the output to show 5 for the first row, then 4 for the second row, 3 for the 3rd row, 2 fourth row and so on (as shown below).
Dave Jackson |TEXT BOX| |DROP-DOWN| 5
Bobby Brown |TEXT BOX| |DROP-DOWN| 4
Daniel Grey |TEXT BOX| |DROP-DOWN| 3
Richard Green |TEXT BOX| |DROP-DOWN| 2
David Bolt |TEXT BOX| |DROP-DOWN| 1
Jason Moore |TEXT BOX| |DROP-DOWN| 6
How can this be done?
EDIT:
print_r($_SESSION['arrayPoints']);
outputs:
Array ( [0] => 5 [1] => 4 [2] => 3 [3] => 2 [4] => 1 [5] => 6 )
-The While loop: while ($data = mysqli_fetch_assoc($result)) { is a query fetch action.
-Each row shown in the image above is in order with each number in the array. So first row = 5 , second row = 4 and so on.
Thanks in advance.
Your current code says that you want to print every number for each data fetched from DB, which is not what you want. You want a single number printed for each data. So forget the foreach. What you need is:
echo $_SESSION['arrayPoints'][$i];
where $i is the current row being fetched (you need to set and increment it).

Extracting string with regexp

In a text file, I have the folowing strings :
ID | LABEL | A | B | C
--------------------------------------
9999 | Oxygen Isotopes | | 0.15 | 1
8733 | Enriched Uranium | | 1 | 1
I would like to extract the fields ID and LABEL of each line using regular expression.
How I can achieve it ?
I am not certain why you insisted on regex.
As the column appear to be separated by | symbol, it seems like using PHP function explode would be an easier solution.
You would be able loop through the lines, and refer to each column using typical array index notation, for example: $line[0] and $line[1] for ID and LABEL respectively.
I doubt regex is the best solution here.
Try this to separate the text file into an array of lines (this might or might not work, depending on the OS of the machine you created the txt file on)
$lines = explode($text, "\n");
$final_lines = array();
foreach ($lines as $line) {
$parts = explode($line, " | ");
$final_lines[] = $parts;
}
Now you can access all of the data through the line number then the column, like
$final_lines[2][0]
Will contain 8733.
You could use preg_split on every line:
$array = preg_split(`/\s*\|\s*/`, $inputLine, 2);
Then as in djdy's answer, the ID will be in $array[0] and the label in $array[1].
No regex needed:
<?php
$file = file('file.txt');
$ret = array();
foreach($file as $k=>$line){
if($k<2){continue;}
list($ret['ID'][],
$ret['LABEL'][],
$ret['A'][],
$ret['B'][],
$ret['C'][]) = explode('|',$line);
}
print_r($ret);
//Label: Oxygen Isotopes ID:9999
echo 'Label: '.$ret['LABEL'][0].' ID:'.$ret['ID'][0];
/*
Array
(
[C] => Array
(
[0] => 1
[1] => 1
)
[B] => Array
(
[0] => 0.15
[1] => 1
)
[A] => Array
(
[0] =>
[1] =>
)
[LABEL] => Array
(
[0] => Oxygen Isotopes
[1] => Enriched Uranium
)
[ID] => Array
(
[0] => 9999
[1] => 8733
)
)
*/
?>
Regular expressions might not be the best approach here. I'd read in each line as a string, and use String.explode("|", input) to make an array of strings. The 0 index is your ID, the 1 index is your label, and so on for A, B, and C if you want. That's a more robust solution than using regex.
A regular expression that gets the ID might be something like
\d{4} |
You could do something similar for the label field, bug again, this isn't as robust as just using explode.
Though its not a best approach to use regular expression here but one may be like this
preg_match_all("/(\d{4}.?)\|(.*?)\|/s", $data, $matchs)
2nd and 3rd index of $matches will carry the required data
Try
$str = file_get_contents($filename);
preg_match_all('/^\s*(\d*)\s*\|\s*(.*?)\s*\|/m', $str, $matches);
// $matches[1] will have ids
// $matches[2] will have labels

Summarize array in PHP

I'm mainly programming in language that used for business systems, and there is a useful built-in function that can sum an array. For example, we've got array like this:
red | 1
red | 1
green | 1
orange | 2
orange | 1
orange | 1
blue | 1
After using summarizing function we get
red | 2
green | 1
orange | 4
blue | 1
Is it equivalent function in php?
UPD.
$array = array('red'=>1,'red'=>2,'green'=>1....);
In php
red | 1
red | 1
green | 1
orange | 2
orange | 1
orange | 1
blue | 1
This kind of array is not possible. PHP array can not have multiple index keys with the same name. It will override the previous one.
As said, an array like
array('red'=>1,'red'=>2,'green'=>1....);
is not possible. Try it and make a print_r. You will see that there is only one red entry with value 2 (or what ever the last value is). The last one will overwrite the previous ones.
Depending on how you create the array, you can either sum the value on the fly, e.g.
for(...) {
if(!isset($array[$color])) {
$array[$color] = 0;
}
$array[$color] += $value;
}
or create a multidimensional array:
$array = array(
'red'=> array(1,2),
'green'=> array(1),
...
);
You can then array_map to loop over it and compute the sums of each entry with array_sum:
$newarray = array_map('array_sum', $array);
Your initial array should contain only values. You can use array_values() for that. After that you can count the values with array_count_values()
http://php.net/manual/en/function.array-count-values.php
supposed you have array like this:
$array = array(
'red | 1',
'red | 1',
'green | 1',
'orange | 2',
'orange | 1',
'orange | 1',
'blue | 1'
);
You can process it this way:
<?php
//process the array data
$temp_output = array();
foreach( $array as $raw)
{
list($name, $value) = array_map('trim', explode("|", $raw));
if( !isset($temp_output[ $name ] ) )
$temp_output[ $name ] = (int)$value;
else
$temp_output[ $name ] += (int)$value;
}
//now, print the value
foreach( $temp_output as $key => $data)
{
echo "{$key} | {$data}\n";
}
?>

returning a record in array based on highest value with php?

Original data looks like this: banners/ad_1.png | Banner ad 1 | 1
Here is an array using the print_r function on it:
Array ( [0] => banners/ad_1.png Banner ad 1 1
[1] => banners/ad_2.png Banner ad 2 2
[2] => banners/ad_3.png Banner ad 3 3 )
This is after exploding it with a | delimiter, so it's separated by img src, alt text, num times viewed.
Is there a way I can return the banner information by num times viewed, max or min?
I have been playing with min, max, array_values, array_keys, array_multisort.. I can't figure it out.
Thanks!
This should work, provided this array doesn't get so big that it eats up significant chunks of memory:
<?php
$array = array(
'banners/ad_1.png | Banner ad 1 | 1',
'banners/ad_2.png | Banner ad 2 | 2',
'banners/ad_3.png | Banner ad 3 | 3'
);
$sort = array();
foreach ($array as $row)
{
$row = explode(" | ", $row); // split up string into a format we can deal with
// use a unique index so we can keep track of association
$idx = trim($row[0]);
$sort[$idx] = trim($row[2]);
}
arsort($sort); // sorts by value in descending order, keeps index association
print_r($sort);
/*
Should be:
Array(
'banners/ad_3.png' => 3,
'banners/ad_2.png' => 2,
'banners/ad_1.png' => 1
)
*/
Here's some documentation on the arsort function I used.

Categories