Is it possible to convert specific text file content into a php array ?
For example:
Text file
//group
1
// first id other values
1 5 7 3 83 83 83 1
2 6 7 3 86 83 83 4
3 3 7 3 63 83 83 7
4 3 7 3 84 83 86 1
end
//group
2
// first id other values
1 3 7 3 83 83 83 1
2 6 7 3 86 83 83 4
3 3 7 3 63 83 83 7
4 3 7 3 84 83 86 1
end
Return php array
1 => array(
1 => array(5, 7, 3, 83, 83, 83, 1),
2 => array...
),
2 => array(
1 => array(3, ...),
....
and so on, until end then next number group, and also ignore comments lines // or #
I've got another solution:
<?php
header('Content-type: text/plain');
$string = "//group
1
// first id other values
1 5 7 3 83 83 83 1
2 6 7 3 86 83 83 4
3 3 7 3 63 83 83 7
4 3 7 3 84 83 86 1
end
//group
2
// first id other values
1 3 7 3 83 83 83 1
2 6 7 3 86 83 83 4
3 3 7 3 63 83 83 7
4 3 7 3 84 83 86 2
end";
$string = preg_replace('/[^0-9 \n]/','',$string);
$array = array_filter(explode("\n", $string));
$temp_array = array();
$new_array = array();
$index = -1;
foreach($array as $key => $arr){
if(strlen(trim($arr)) == 1 && intval($arr) > 0){
$index = intval($arr);
}
else if(strlen(trim($arr)) > 4){
$temp_array = array_values(array_filter(explode(" ", $arr)));
$temp_index = $temp_array[0];
unset($temp_array[0]);
$new_array[$index][$temp_index] = $temp_array;
}
}
print_r(array_filter($new_array));
?>
Solved...
Text file
// group 1
1
1 4 3 "ssssssss"
end
// group 2
2
1 5 4 "ssssssss s"
end
// group 3
3
1 6 5 "ssssssss ss"
end
php convert code
$list = array();
$handle = fopen('Item.txt', 'r');
while(($line = fgets($handle)) !== false)
{
// skip comments
if(preg_match('!^//!', $line) || preg_match('/#/', $line))
{
continue;
}
// replace all spaces
$line = preg_replace('~"[^"]*"(*SKIP)(*F)|\s+~', ',', $line);
// skip blanks
if($line[0] == ',')
{
continue;
}
// define group
if(substr_count($line, ',') == 1 || substr_count($line, 'end') == 1)
{
if(substr_count($line, 'end') == 0)
{
$key = str_replace(',', '', $line);
}
continue;
}
// remove last comma
if(substr($line, -1) == ',')
{
$line = substr($line, 0, -1);
}
$arguments = explode(',', $line);
$id = $arguments[0];
unset($arguments[0]);
$list[$key][$id] = $arguments;
}
fclose($handle);
print_r($list);
output http://prntscr.com/6emxpq
Related
I'm doing social service, the idea is to automatize a process. I already capture other values using regex, like:
<?php function LeerEncabezado() {
$fh = fopen('RPREGFM_________007_001.txt', 'r') or die('lel'); $file =
str_replace(',', '',
file_get_contents("RPREGFM_________007_001.txt")); $f =
fopen("RPREGFM_________007_001.txt", "w"); fwrite($f, $file);
fclose($f); while (!feof($fh)) {
$line = fgets($fh);
//Intermedio
if (preg_match('/INTERMEDIO (?<cfintermedio>[\w]+.+)/i', $line, $r1)) {
$CFINTERMEDIO = substr($r1['cfintermedio'], 13, 8);
echo "C.F. Intermedio: $CFINTERMEDIO";
echo '<br/>';
}
//Base
if (preg_match('/BASE (?<cfbase>[\w]+.+)/i', $line, $r2)) {
$CFBASE = substr($r2['cfbase'], 13, 8);
echo "C.F. Base: $CFBASE";
echo '<br/>';
}
//kVArh
if (preg_match('/F.P. (?<fp>[\d]+.+)/i', $line, $r3)) {
$anioi = substr($r3['fp'], 0, 5);
echo "kVArh: $anioi";
echo '<br/>';
echo "--------------------------------------</br>";
}
//Base promedio
if (preg_match('/201912 (?<fp>[\d]+.+)/i', $line, $r3)) {
$anioi = substr($r3['fp'], 8, 5); // echo "kVArh: $anioi";
echo '<br/>';
echo "--------------------------------------</br>";
}
} } LeerEncabezado();
fclose($fh);
And it's working until his point, I got to take 3 values from that text block, the last number in INTERM column, BASE and % M$. In this receipt, it would be 1,5,99.98%. I've used strg_replace before for, I guess ill use it for the %. So I can compare those variables with other in the same receipt.
How can I extract those value taking in mind that the 201912 it's going to change taking in consideration the year and the number of rows in MES might change? Pretty much used the blank space and the read the previous line which it's going to be the one where the 3 values are in?
MES TOTAL PUNTA INTERM BASE TOT PTA INT BAS % M$
201901 9 1 7 744 122 622 99.96
201902 8 1 6 672 107 565 99.97
201903 9 1 7 744 115 629 99.97
201904 9 2 7 719 122 597 99.97
201905 10 1 8 744 88 656 99.98
201906 10 1 8 720 80 640 99.97
201907 12 2 10 744 92 652 98.89
201908 13 2 11 744 88 656 97.74
201909 11 1 9 720 80 640 97.05
201910t 1 7 624 76 548 97.56
201910 10 1 120 20 100 98.80
201911 8 1 6 721 115 606 99.20
201912 7 1 5 744 117 627 99.98
I want to combine the two arrays in my results
MY CODE
<?php
/* Designated level for each exp
Level 2 - 23 exp
Level 3 - 34 exp
Level 4 - 45 exp
Level 5 - 56 exp
Level 6 - 68 exp
Level 7 - 79 exp
Level 8 - 90 exp
Level 9 - 101 exp
Level 10 - 112 exp
Level 11 - 123 exp
Level 12 - 134 exp
Level 13 - 145 exp
Level 14 - 156 exp
Level 15 - 168 exp
Level 16 - 179 exp
*/
$limit = 100000-99318;
// Level
$arrlevel = array ('Level 2','Level 3','Level 4','Level 5','Level 6','Level 7','Level 8','Level 9','Level 10','Level 11','Level 12','Level 13','Level 14','Level 15','Level 16');
// Exp
$array = array (23,34,45,56,68,79,90,101,112,123,134,145,156,168,179);
$array = array_filter($array, function($var) use ($limit) {
return ($var <= $limit);
});
$num = count($array);
$total = pow(2, $num);
$out = array();
for ($i = 0; $i < $total; $i++) {
$comb = array();
for ($j = 0; $j < $num; $j++) {
// is bit $j set in $i?
if (pow(2, $j) & $i){
$comb[] = $array[$j];
}
}
if (array_sum($comb) == $limit)
{
$out[] = $comb;
}
}
array_multisort(array_map('count', $out), SORT_ASC, $out);
$out = array_unique($out, SORT_REGULAR);
$m = 1;
foreach($out as $result)
echo "<b>Possible Answer ". $m++. " : </b> " .implode(', ', $result)."
<br><br>";
?>
Output:
Possible Answer 1 :
23, 34, 45, 68, 79, 90, 112, 179
Possible Answer 2 :
23, 34, 45, 68, 79, 90, 123, 168
Possible Answer 3 :
23, 34, 45, 68, 79, 101, 112, 168
I want the ouput like this
Possible Answer 1 :
Level 2 - 23 | Level 3 - 34 | Level 4 - 45 | Level 6 - 68 | Level 7 - 79 | Level 8 - 90 | Level 10 - 112 | Level 16 - 179
-----------------------------------------
I want to combine the two arrays
(This program is about finding all combination to reach the result [Subset sum program])
You might use a mapper for the entries of Level n and the experience.
Then for the $result array in the loop you could use array_map and for each item that you are mapping use the value as the key for the $mapper array and implode using |
That will format all the possible answers in this format:
Possible Answer 1 :
Level 3 - 34 | Level 13 - 145 | Level 14 - 156 | Level 15 - 168 | Level 16 - 179
For example
$mapper = [
23 => "Level 2",
34 => "Level 3",
45 => "Level 4",
56 => "Level 5",
68 => "Level 6",
79 => "Level 7",
90 => "Level 8",
101 => "Level 9",
112 => "Level 10",
123 => "Level 11",
134 => "Level 12",
145 => "Level 13",
156 => "Level 14",
168 => "Level 15",
179 => "Level 16",
];
foreach($out as $result)
echo "<b>Possible Answer ". $m++. " : </b> " .implode(' | ', array_map(function($x) use ($mapper) {
return $mapper[$x] . " - " . $x;
}, $result))."
<br><br>";
Php demo
Just do it and do sort
$combine=array_combine($arrlevel,$array);
Brief idea of what I'm doing is taking lines of writing that are always in same format which I'm using
$result = $_POST['result'];
$result = explode(" ",$result);
foreach($result as $k => $v){
${"var".$k} = $v;
}
$var11 = trim($var11, "(");
$var18 = trim($var18, "(");
$var25 = trim($var25, "(");
$var32 = trim($var32, "(");
and then picking out the variables I need to insert into my database
The format of the text string
[18:20:23] Neptune> At [18:20] on Table 40: SassyNClassy G( 4 - 288 ) TipMeGood B( 1 - 174 ) StandUpMan Y( 0 - 23 ) Ruby2017 R( 0 - 10 )
varaibles below
Which echos out into these variables
$var1 = [18:20:23]
$var8 = 40:
$var9 = SassyNClassy
$var11 = G
$var12 = 4
$var14 = 288
$var16 = TipMeGood
$var18 = B
$var19 = 1
$var21 = 174
$var23 = StandUpMan
$var25 = Y
$var26 = 0
$var28 = 23
$var30 = Ruby2017
$var32 = R
$var33 = 0
$var35 = 10
Now what I am looking for is if it is possible how would I go about linking variables Green (9 11 12 14) blue (16 18 19 21) yellow (23 25 26 28) red (30 32 33 35)
and reordering them so that its blue green red yellow keeping in mind the order of colours changes based on the string input
I will be doing a input into my table which I can do but I need to have it all in same order for other php code I'm in process of writing to add the 3rd variable of (blue and green) and of (red and yellow) as well as the scores of those 2 teams
UPDATED
Here are a few examples of what are posted via
$result = $_POST['result'];
[18:20:23] Neptune> At [18:20] on Table 40: SassyNClassy G( 4 - 288 ) TipMeGood B( 1 - 174 ) StandUpMan Y( 0 - 23 ) Ruby2017 R( 0 - 10 )
What it should be in order
TipMeGood B 1 174 SassyNClassy G 4 288 StandUpMan Y 0 23 Ruby2017 R 0 10
[18:21:50] Neptune> At [18:21] on Table 35: oldstray Y( 4 - 288 ) MeanyBritches R( 2 - 188 ) racing_2425 B( 0 - 60 ) ladyhawk__ G( 0 - 20 )
What it should be in order
racing_2425 B 0 60 ladyhawk__ G 0 20 MeanyBritches R 2 - 188 oldstray Y 4 288
[18:22:01] Neptune> At [18:22] on Table 25: junesnugglebug R( 4 - 288 ) WhamBam_Booty G( 2 - 213 ) Misfitting B( 2 - 178 ) kfallsgrl Y( 0 - 137 )
What it should be in order
Misfitting B 2 178 WhamBam_Booty G 2 213 junesnugglebug R 4 288 kfallsgrl Y 0 137
Im trying to make a table consist some sort of cinema seat from A[1-20] to J[1-20]. I have a txt file which contain seats that are reserved, like this:
A2;
A1;
A3;
A7;
if a seat is reserved, the bgcolor of table must be red. This is the full code:
<?php
$file = fopen($path,"r") or exit("cant open file");
$seat="";
while(!feof($file))
{
$seat.= fgets($file);
}
$seat_splitted = explode(";",$seat);
fclose($file);
$arrTable[]="";
$letter="";
$tableContent="";
for($i = 0,$counter=0;$i<10;$i++,$counter++)
{
if($i==0)
$letter="A";
else if($i==1)
$letter="B";
else if($i==2)
$letter="C";
else if($i==3)
$letter="D";
else if($i==4)
$letter="E";
else if($i==5)
$letter="F";
else if($i==6)
$letter="G";
else if($i==7)
$letter="H";
else if($i==8)
$letter="I";
else if($i==9)
$letter="J";
?>
<tr>
<?php
for($j = 1;$j<21;$j++)
{
$arrTable[$counter]= $letter.$j;
foreach($seat_splitted as $value)
{
if(strcmp($value,$arrTable[$counter])==0)
//if($value == $letter.$j)
{
$GLOBALS['color']="red";
break;
}
else
$GLOBALS['color']="white";
}
?>
<td bgcolor="<?php echo $GLOBALS['color']; ?>"> <?php echo $arrTable[$counter]?> </td>
<?php
$counter++;
}
?>
</tr>
<?php
}
?>
I dont know why when if(strcmp($value,$arrTable[$counter])==0) or //if($value == $letter.$j), its only catch the first seat which is "A2". But when i change the txt file to this:
A2;A1;A3;A7;
the IF can catch them all. Is it wrong to concatenate string like this? $seat.= fgets($file);. What can i do to make it work with the first txt file? Sorry for my bad english.
I think something like this should work for you. I simplified everything a bit.
1. First I create an array ($seats) with all seats in it. Which has a structure like this:
Array
(
[A] => Array
(
[1] => free
[2] => free
[3] => free
//...
//...
2. After this I get all reserved seats from the file into an array. (A better solution would be if you have all this data in a database!)
3. Then I loop through each reserved seat and also set it to that in the $seats array, so that it gets something like this:
Array
(
[A] => Array
(
[1] => reserved
[2] => free
[3] => reserved
//...
//...
4. At the end I simply print the table
Code:
<?php
//create seats
$rows = range(strtoupper("A"), strtoupper("J"));
$columns = range(1, 20);
$seats = array_combine($rows, array_map(function($v)use($columns){
return array_combine($columns, array_fill(0, count($columns), "free"));
}, $rows));
//get reserved seats
$reservedSeats = array_map(function($v){
return trim($v, ";");
}, file("test.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
//set reserved seats
foreach($reservedSeats as $reserved) {
$checkOne = preg_replace("/[^A-Z]*/", "", $reserved);
$checkTwo = preg_replace("/[^0-9]*/", "", $reserved);
if(isset($seats[$checkOne]) && isset($seats[$checkOne][$checkTwo]))
$seats[$checkOne][$checkTwo] = "reserved";
}
//print seats
$reservedColor = "red";
$defaultColor = "white";
$rowColor = "green";
echo "<table border='1'>";
foreach($seats as $row) {
echo "<tr><td bgcolor='" . $rowColor . "'>" . $rowKey . "</td>";
foreach($row as $key => $seat)
echo "<td bgcolor='" . ($seat == "reserved"?$reservedColor:$defaultColor) . "'>" . $key . "</td>";
echo "</tr>";
}
echo "</table>";
?>
output (without colors):
A 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
B 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
D 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
E 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
F 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
G 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
H 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
I 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
J 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
IF you use the explode as you do, you will get an array of:
["A2","\nB1","\nC3"...]
So you have to deal with the \n
Maybe you could have a try as explode(";\n",$seat)
Update: in some system u need to use \r\n. So here is the correct final solution: explode(";\r\n",$seat)
How I can change this:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 11
[8] => 21
[9] => 22
[10] => 23
[11] => 24
)
To this:
1-7, 11, 21-24
I have a list of numbers like this in PHP array, and I just want to make this list a little bit smaller.
2000: 3 6 7 11 15 17 25 36 42 43 45
2001: 2 3 4 5 6 9 10 11 12 13 34 37 45 46 47 48 49 50 51 52
2002: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 33 34 35 36 37 39 40 41 42 43 44 45 46 47 48 49 50 51 52
2003: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
2004: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 21 22 23 24 25 26 27 28 29 30 31 32 33 34 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
2005: 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
2006: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
2007: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
Interesting task.
Here's a demo script that does exactly what you want.
Tweak to taste.
Code
<?php
$groups = array();
$active_group = 0;
$output = array();
$output_counter = 0;
$nums = array( 1, 2, 3, 4, 5, 6, 7, 11, 21, 22, 23, 24 );
foreach( $nums as $k => $num ) {
// if this isn't the first item, and the current number
// isn't one more than the previous one, increment the counter
if( $k !== 0 && $nums[$k] !== $nums[$k-1]+1 )
$active_group ++;
// add this number to a group
$groups[ $active_group ][] = $num;
}
// take the 1st and last of each group
foreach( $groups as $group ) {
$first = array_shift( array_values($group) );
$output[$output_counter][] = $first;
$last = array_pop( array_values($group) );
if( $first !== $last )
$output[$output_counter][] = $last;
$output_counter++;
}
echo '<pre>';
print_r($output);
?>
Output
Array
(
[0] => Array
(
[0] => 1
[1] => 7
)
[1] => Array
(
[0] => 11
)
[2] => Array
(
[0] => 21
[1] => 24
)
)
A single loop will do. You need need to keep track of the "previous" iteration's value and the "starting" value for storing ranged data.
Code:
$prev = -1; // initialize out of range
foreach ($numbers as $n) {
if (!isset($start)) { // first iteration
$start = $n; // declare $start
} elseif ($n != $prev + 1) { // not consecutive
$result[] = $start == $prev ? $prev : "$start-$prev"; // store single or ranged values
$start = $n; // update $start
}
$prev = $n; // declare / update $prev
}
$result[] = $start == $prev ? $prev : $start . '-' . $prev; // store final iteration data
echo implode(', ', $result); // comma delimit the values
Output from: $numbers = [1, 2, 3, 4, 5, 6, 7, 11, 21, 22, 23, 24]; (Demo)
1-7, 11, 21-24
Output from: $numbers = [1, 3, 5, 6, 11, 21, 22, 23, 24, 26]; (Demo)
1, 3, 5-6, 11, 21-24, 26
Here is a way to both compress an array of integers into the string format you want and to expand that string format back out to an array of integers.
function compress($expanded) {
$low = -1;
$prevNum = -1;
$expanded = array_unique($expanded);
sort($expanded, SORT_NUMERIC);
foreach($expanded as $num) {
if($low == -1) {
$low = $num;
} else if($num - $prevNum > 1) {
$compact[] = ($prevNum - $low >= 1) ? sprintf("%d-%d", $low, $prevNum) : $prevNum;
$low = $num;
}
$prevNum = $num;
}
if($low != -1 ) {
$compact[] = ($num - $low >= 1) ? sprintf("%d-%d", $low, $num) : $num;
}
return implode(",", $compact);
}
public static function expand($compact) {
$expanded = Array();
$compact = explode(",", $compact);
foreach($compact as $num) {
if( is_numeric($num) ) {
$expanded[] = $num;
} else {
list($low, $high) = explode("-", $num);
if( is_numeric($low) && is_numeric($high) && $low < $high) {
for($i = $low;$i <= $high;$i++) {
$expanded[] = $i;
}
}
}
}
return $expanded;
}
//Placeholder array
$b = array();
// Slice array (where to slice)
$s = array(11, 21);
foreach ($array as $year => $a) {
for($i = 0; $i < count($a); $i++) {
for($ii = 0; $ii < count($s); $ii++) {
if($i == 0) {
$b[$year]['<' . $s[$ii]][] = $a[$i];
break;
} else if ( isset($a[$i+1]) && $a[$i] < $s[$ii] && $a[$i+1] >=$s[$ii]){
$b[$year]['<' . $s[$ii]][] = $a[$i];
if (isset($s[$ii+1])) {
$b[$year]['<' . $s[$ii+1]][] = $a[$i+1];
} else {
$b[$year]['>' . $s[$ii]][] = $a[$i+1];
}
break;
} else if ( !isset($s[$ii+1]) && $i == count($a) - 1) {
$b[$year]['>' . $s[$ii]][] = $a[$i];
break;
}
}
}
}
$array
The list of numbers
OUTPUT ($b):
array
2000 =>
array
'<11' =>
array
0 => int 3
1 => int 7
'<21' =>
array
0 => int 11
1 => int 17
'>21' =>
array
0 => int 25
1 => int 45
2001 =>
array
'<11' =>
array
0 => int 2
1 => int 10
'<21' =>
array
0 => int 11
1 => int 13
'>21' =>
array
0 => int 34
1 => int 52
2002 =>
array
'<11' =>
array
0 => int 1
1 => int 10
'<21' =>
array
0 => int 11
1 => int 20
'>21' =>
array
0 => int 21
1 => int 52
2003 =>
array
'<11' =>
array
0 => int 1
1 => int 10
'<21' =>
array
0 => int 11
1 => int 20
'>21' =>
array
0 => int 21
1 => int 51
2004 =>
array
'<11' =>
array
0 => int 1
1 => int 10
'<21' =>
array
0 => int 11
1 => int 19
'>21' =>
array
0 => int 21
1 => int 52
2005 =>
array
'<11' =>
array
0 => int 1
1 => int 10
'<21' =>
array
0 => int 11
1 => int 20
'>21' =>
array
0 => int 21
1 => int 52
2006 =>
array
'<11' =>
array
0 => int 1
1 => int 10
'<21' =>
array
0 => int 11
1 => int 20
'>21' =>
array
0 => int 21
1 => int 52
2007 =>
array
'<11' =>
array
0 => int 1
1 => int 10
'<21' =>
array
0 => int 11
1 => int 20
'>21' =>
array
0 => int 21
1 => int 52
NOTE: Just change the values (11) and (21) to suit your needs. You can add more values.
Heres an example:
$query = "SELECT '1-11' Range, COUNT(rank) rank
FROM promoted WHERE rank between 1 and 11
union all
SELECT '12-21' Range, COUNT(rank) rank
from promoted
where rank between 12 and 21
union all
SELECT '22-31' Range, count(rank) rank
from promoted
where rank between 22 and 31
union all
SELECT '32-40' Range, count(rank) rank
from promoted
where rank between 22 and 31
union all
SELECT rank, count(rank) FROM promoted WHERE rank = '40'";