Get record from csv by column name - php

I have a csv table (my csv file http://jpst.it/1GCd9)
| id | email | name | google.com | yahoo.com |
| 1 | email1#email.com | jack | | + |
| 2 | email2#email.com | jack | + | |
| 3 | email3#email.com | jack | | |
Is it possible to get emails that have "+" by column name?
For example I want to specify google.com and get email email2#email.com
I just know how to get data by column id :(
while (($row = fgetcsv($fileHandle, 0, ",")) !== FALSE) {
if($flag) { $flag = false; continue; }
$explode = explode(";",$row[4]);
echo $explode[4]. ", ";
}

By using sanitized CSV (removing all the excess white space and array filter you can get what you want.
I used array_map('trim', array_filter(explode($delimeter, $lines[0]), function($entry){return !empty($entry);})); to sanitize all input from whitespaces, and discard the "empty" header you have at the end by the last pipe character.
See the following functions: array_map, trim, array_filter.
Then when everything is "normalized" we have an array of associative arrays with the correct fields, so we can search by using array_filter again. The variable $only_with_plus will then only contain associative arrays that match the search parameters.
$only_with_plus = array_filter($entries, function($entry) {
return $entry['google.com'] == '+' && $entry['email'] = 'email2#email.com';
});
See it online: https://ideone.com/ZDn2dv
<?php
$CSV = <<<EOF
| id | email | name | google.com | yahoo.com |
| 1 | email1#email.com | jack | | + |
| 2 | email2#email.com | jack | + | |
| 3 | email3#email.com | jack | | |
EOF;
$delimeter = '|';
$lines = explode("\n", $CSV);
$key_names = array_map('trim', array_filter(explode($delimeter, $lines[0]), function($entry){return !empty($entry);}));
$entries = [];
$len = count($lines);
for($c = 1; $c < $len; $c++) {
$line = array_map('trim', array_filter(explode($delimeter, $lines[$c]), function($entry){return !empty($entry);}));
$entry = [];
foreach($line as $key => $value) {
$entry[$key_names[$key]] = $value;
}
$entries[] = $entry;
}
$only_with_plus = array_filter($entries, function($entry) {
return $entry['google.com'] == '+' && $entry['email'] = 'email2#email.com';
});
var_dump($only_with_plus);
// your code goes here

You cant filter csv directly, but you can filter it after parsing it to array;
http://sandbox.onlinephpfunctions.com/code/f17969e35fcfc5e2f4b2f25202359f1b4cc4840b

Related

PHP: Generate word combination from the word with the same category

I want to generate two word combination from the word with the same category. Example I have this table:
+--------------+----------+
| Word | Category |
+--------------+----------+
| human | social |
| politic | social |
| law | social |
| artificial | science |
| intelligence | science |
+--------------+----------+
and I want the output like this:
+-------------------------+----------+
| Word | Category |
+-------------------------+----------+
| human-law | social |
| human-politic | social |
| politic-law | social |
| artificial-intelligence | science |
+-------------------------+----------+
But I have no idea how to do that. This is my code, and this code just combine all word without category filter.
Model Class (md_classification):
function getWords(){
$stat = $this->db->query("SELECT DISTINCT(word), category from tb_words group by word, category");
return $stat->result_array();
}
function getAllCombinations($array){
$combinations = array();
foreach ($array as $x)
foreach ($array as $y) {
if ($x != $y && !in_array($y . '-' . $x, $combinations))
array_push($combinations, $x . '-' . $y);
}
return $combinations;
}
Controller:
$getWord = $this->md_classification->getWords();
foreach ($getWord as $row) {
$word[] = $row['word'];
$category[] = $row['category'];
}
$result = $this->md_classification->getAllCombinations($word);
your current getAllCombinations function will give you reverse duplcates since you are iterating on all indexes inside a nested loop.
I think the answer here is using a basic for loop as follows
function getAllCombinations($array){
$combinations = array();
for ($i = 0; $i < sizeof($array); $i++)
for ($j = $i+1; $j < sizeof($array); $j++)
if ($array[$i]['category'] == $array[$j]['category'])
array_push($combinations, $array[$i]['word'] . '-' . $array[$j]['word']);
return $combinations;
}
notice that the function should receive the array of results the same way it came from the DB. meaning:
$result = $this->md_classification->getAllCombinations($getWord);
with this method, you won't get any duplicates since you won't iterate on the same rows twice. hope it helped.
I can advice the MySQL solution for this problem:
select concat(w.Word, ' - ', w1.Word) Words, w.Category
from words w
join words w1 on w.Category = w1.Category
where w.Word < w1.Word
;
result:
+===========================+==========+
| Words | Category |
+===========================+==========+
| human - politic | social |
+---------------------------+----------+
| law - politic | social |
+---------------------------+----------+
| human - law | social |
+---------------------------+----------+
| artificial - intelligence | science |
+---------------------------+----------+
test SQL code here

Using php laravel code: Leave the cell (exported excel) empty if an array is duplicate

I am using php laravel. I'm trying to export the data into excel .csv file with unique data or leaving the cell empty instead of duplicating the data. What filter should I use to do that? To be clear I will show some illustrationThis is an example of the Excel View with the data from the array which is exported using php:
+--------+------------+-----------+
| Group | First Name | Last Name |
+--------+------------+-----------+
| Group1 | John | Doe |
+--------+------------+-----------+
| Group1 | Jane | Doe |
+--------+------------+-----------+
| Group2 | John | Smith |
+--------+------------+-----------+
| Group2 | Jane | Smith |
+--------+------------+-----------+
This is an example of Excel View that I need. You can see that the duplicating groups are hidden:
+--------+------------+-----------+
| Group | First Name | Last Name |
+--------+------------+-----------+
| Group1 | John | Doe |
+--------+------------+-----------+
| | Jane | Doe |
+--------+------------+-----------+
| Group2 | John | Smith |
+--------+------------+-----------+
| | Jane | Smith |
+--------+------------+-----------+
And this is the code that I've been using:
public function getDashboardBookingsReport2($account_alias, $group_alias){
header (...)
$file = fopen('php://output', 'w');
fputcsv($file, array('Group Name', 'First Name', 'Last Name'));
$table = (...)
$rowed[] = array(
$egroup->name, // Group
$user->first_name, // First Name
$user->last_name, // Last Name
);
}
}
}
(...)
$data = $rowed;
uasort($data, function($a, $b) {
return strcmp($a[0], $b[0]);
});
foreach ($data as $row)
{
fputcsv($file, $row);
}
exit();
return Redirect::to( $group_alias.'/app/dash' );
}
Add this code just before foreach ($data as $row) and after uasort($data, function($a, $b):
for($i = count($data) - 1; $i > 0; $i--) {
if($data[$i][0] === $data[$i - 1][0]) {
$data[$i][0] = "";
}
}

Combine csv column values in PHP

I have a csv file with 5 rows :
id | price| name | sku | qty
1 | 22 | widget0 | abcd | 1
2 | 21 | widget1 | efgh | 1
3 | 10 | widget0 | abcd | 2
4 | 44 | widget1 | efgh | 1
5 | 22 | widget4 | mnop | 1
etc...
The first 3 columns are just here for visual purpose and are not used for what I need to achieve.
What I need to do is read the sku and qty data in the file and output the result.
I have to count the number of the same skus and get the total qty per sku.
Based on the example above, I need :
sku | qty
abcd | 3
efgh | 2
ijkl | 1
mnop | 1
With the following code, I can get the total number of the same skus in the file :
$file = ('my.csv');
$fh = fopen($file, 'rb');
$tag = array();
$qty = array();
$row=1;
while($col = fgetcsv($fh)) {
if($row == 1){ $row++; continue; } //skip 1st row
$num = count($fh);
if (isset($tag[$col[3]])) {
$tag[$col[3]]++;
}
else {
$tag[$col[3]] = 1;
}
}
print_r($tag);
It gives me :
sku | qty
abcd | 2
efgh | 2
ijkl | 1
mnop | 1
Which is not correct. I don't know how to get the qty column value and associate it to the total number of skus value in the csv file.
Any thoughts ?
Use below code for your solution
$file = ('my.csv');
$fh = fopen($file, 'rb');
$tag = array();
$qty = array();
$row=1;
while($col = fgetcsv($fh)) {
if($row == 1){ $row++; continue; } //skip 1st row
$num = count($fh);
if (isset($tag[$col[3]])) {
//$tag[$col[3]]++;
$tag[$col[3]] = (int)$tag[$col[3]] + (int)$col[4]; // where $col[4] = qty with forcing to `int` value
}
else {
$tag[$col[3]] = $col[4];
}
}
print_r($tag);
you need to make SUM of quantity instead just increase with +1
Hope this will help!
try this solution
$file = ('my.csv');
$fh = fopen($file, 'rb');
$tag = array();
$qty = array();
$row=1;
//skip first row
fgetcsv($fh, 10000, ",");
while($col = fgetcsv($fh,10000)) {
$num = count($fh);
if (isset($tag[$col[3]])) {
$tag[$col[3]]++;
}
else {
$tag[$col[3]] = 1;
}
}
print_r($tag);

Stop Words Filtering for some documents

I confused how to filter words of some documents. I have to checked out the documents one by one. for example from tb_tokens :
======================================================================
| tokens_id | tokens_word | tokens_freq| sentence_id | document_id |
======================================================================
| 1 | A | 1 | 0 | 1 |
| 2 | B | 1 | 0 | 1 |
| 3 | C | 1 | 1 | 1 |
| 4 | D | 1 | 0 | 2 |
| ... | | | | |
======================================================================
I have to remove all words that appear on a list od common words like “and”, “the”, etc.. The list recorded in table tb_stopword and then remove words that occurr in large number across most documents that appear on a list recorded in tb_term table.
the function cekStopWord :
function cekStopWord ($word) {
$query = mysql_query("SELECT stoplist_word FROM tb_stopword where stoplist_word = '$word' ");
$row = mysql_fetch_row($query);
if($row > 0) {
return true;
} else {
return false;
}
}
And the similar function for the second process (remove words that occurr in large number across most documents)
function cekTerm ($word) {
$query = mysql_query("SELECT term_word FROM tb_term where term_word = '$word' ");
I confused how to process in every documents. I tried to call by doc_id, but it doesnt work. and here's my code :
//$doc_id is a variable that save array of document_id
$query = mysql_query('SELECT tokens_word, sentence_id, document_id FROM tb_tokens WHERE document_id IN (' . implode(",", $doc_id) . ')') or die(mysql_error());
while ($row = mysql_fetch_array($query)) {
$word[$row['document_id']][$row['sentence_id']] = $row['tokens_word'];
}
foreach ($word as $doc_id => $words){
$cekStopWord = cekStopWord($words);
$cekTerm = cekTerm($words);
if((preg_match("/^[A-Z, 0-9]/", $words))&& (!$cekStopWord) && (!$cekTerm) ){
$q = mysql_query("INSERT INTO tb_tagging VALUES ('','$words','','$sentence_id','$doc_id') ");
and also how to use preg_match in array ?
thank you so much :)

Add array elements between each of the existing array elements

I am trying to create a report in Excel by fetching data from MySql. I need to get subject headings from the database and output them to the excel sheet as columns e.g cell: D5, E5, F5 ... M5 etc.
So far I have managed to do so, therefore the display under the cells holds headings something like:
D5:Mathematics, E5:English, F5:Physics, etc.
| A | B | C | D | E | F | G | H |
--------------------------------------------------------------
1 | | | | | | | | |
...
5 | | | | Mathematics | English | Physics | ... | ... |
which is fine. The challenge is, I need to insert a GRADE heading in between each of the Subjects, something like this:
| A | B | C | D | E | F | G | H | I | J | K |
--------------------------------------------------------------------------------------
1 | | | | | | | | | | | |
...
5 | | | | Mathematics | GRADE | English | GRADE | Physics | GRADE | ... | ... |
Now here is what I have so far:
$stringindex = "DEFGHIJKLMNOPQRSTUVWXYZ"; // For the excel column cells
$arr_index = str_split($stringindex); // create array elements
$arr_val2 = array(); // create array
$subject = array();
$subname2 = array();
while($sub_row = mysqli_fetch_array($resub, MYSQLI_ASSOC)) {
$subject[] = $sub_row['name']; // Get the subjects from the database and put them in an array
}
foreach($subject as $sub => $subname) {
$subkey[] = $sub; // array of subject keys e.g 0|1|2|3
$subname2[] = $subname; // array of subjects
}
foreach($arr_index as $arr => $arr_val) {
$arr_val2[] = $arr_val; // array of letters e.g D|E|F|G
}
$acount = count($subname2);
$bcount = count($arr_val2);
$size = ($acount > $bcount) ? $bcount : $acount;
$a = array_slice($subname2, 0, $size);
$b = array_slice($arr_val2, 0, $size);
$combine = array_combine($a, $b);
$sheet = $objPHPExcel->setActiveSheetIndex(0); // PHPExcel functions
foreach($combine as $key => $val) { // GET SUBJECTS
$objPHPExcel->getActiveSheet()->getColumnDimension($val)->setAutoSize(true); // Sets Column Width
$sheet
->setCellValue($val.'5', $key); // Lists Subjects as columns
} // END of FOREACH LOOP
The above code is able to display the subjects as column headings in excel:
QUESTION:
How do I add a code to add a GRADE column after each subject heading?
I hope you'll point me in the right direction coz' I am now stuck.
Thanks in advance.
You can try something like this:
$stringindex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // For the excel column cells
$columns = str_split($stringindex); // create array elements
$rowIndex = 5; // start at row 5 in Excel
$columnIndex = 3; // start at column D in Excel
$subjects = array();
while($sub_row = mysqli_fetch_array($resub, MYSQLI_ASSOC)) {
$subject[] = $sub_row['name']; // Get the subjects from the database and put them in an array
}
$sheet = $objPHPExcel->setActiveSheetIndex(0); // PHPExcel functions
foreach($subject as $index => $subjectName) { // GET SUBJECTS
$columnName = getColumnName($columnIndex, $columns);
$objPHPExcel->getActiveSheet()->getColumnDimension($columnName)->setAutoSize(true); // Sets Column Width
$sheet->setCellValue($columnName.$rowIndex, $subjectName); // Lists Subjects as columns
$columnIndex++;
$columnName = getColumnName($columnIndex, $columns);
$objPHPExcel->getActiveSheet()->getColumnDimension($columnName)->setAutoSize(true); // Sets Column Width
$sheet->setCellValue($columnName.$rowIndex, "GRADE");
$columnIndex++;
} // END of FOREACH LOOP
function getColumnName($index, $columns) {
$columnName = "";
$numColumns = count($columns);
while($index >= $numColumns) {
$columnName = $columns[($index % $numColumns)] . $columnName;
$index = floor($index / $numColumns) - 1;
}
$columnName = $columns[($index % $numColumns)] . $columnName;
return $columnName;
}
I added a function getColumnName() which gives you "AA", "AB", ... in the event that your subject and grade columns go past the A-Z limit.
$temp=true;
then in the loop that goes through columns:
if($temp==true){
//do stuff
$temp=false;
}else{
//do other stuff
$temp=true;
}

Categories