Hello :) I am stuck in my mini-app developing. I have following text, copied from 3rd party web page:
Type A GZ 600 11.09.2021 12:00 OST 9
Type A GZ 601 11.09.2021 13:20 ADS 1
Type A GZ 602 11.09.2021 21:35 OCS 1
Type A GZ 603 11.09.2021 14:50 CSE 10
Type B GZ 600 11.09.2021 12:00 OST 5
Type B GZ 601 11.09.2021 13:20 ADS 3
Type B GZ 602 11.09.2021 21:35 OCS 6
Type B GZ 603 11.09.2021 14:50 CSE 12
I need to parse it to following format:
$s = 10, $ns = 11, $bs = 26
, like:
echo "S:" . $s . " NS:" . $ns . " BS:" . $bs; // Output: S:10 NS:11 BS:26
where:
$fa = array("OCS", "CSE"); is array of codes
$ns is sum of Type A last column numbers, which 5 column 3-letter code is in the array,
$s is sum of Type A last column numbers, which 5 column 3-letter code is not in the array
$bs is just sum of Type B last column numbers
My code now is following:
if(!empty($_POST['indata'])){
$in_data = $_POST['indata']; // Get POST data
$fa = array("OCS", "CSE"); // Make array
$ns = 0; // Init ns value
$s = 0; // Init ss value
foreach(explode("/n",$in_data) as $line){ // Divide text to lines
$info[] = explode(" ", $line); // Divide line to values and put them to array
print_r($info); //Show input for test purposes
if(in_array($info[4], $fa)) { // Check, if 4th array value (code) is in array
$ns = $ns $info[5]; // plus to $ns, if yes
} else {
$s = $s $info[5]; // plus to $s, if no
}
unset($info); // clear array for next usage
}
}
But it seems not cutting line into array. It just shows me lines, not dividing to array. I am using Summernote text editor, it sends data as rows.
CodePudding user response:
Because you're using $info[] = ...
you get a 2 levels deep array instead of 1 level as your code is expecting. $info[] = ...
basically means "Add the right hand side to $info as one element". So if the right hand side is a string and $info was empty before you'd get [0 => "my string"]
. If the right hand side was an array you'd get [0 => [0 => "my", 1 => "array"]]
.
Do you see what I am getting at? Your code is adding one element to $info, never more than that. So to access anything in $info the first part needs to be $info[0]. But the code looks for the 4th and 5th elements, and they'll never be there. On the other hand, if you'd look for the 4th element inside the 1st one.. That is, $info[0]
for the 1st element, and then the 4th inside it: $info[0][4]
, then you get what you're looking for.
if(!empty($_POST['indata'])){
$in_data = $_POST['indata']; // Get POST data
$fa = array("OCS", "CSE"); // Make array
$ns = 0; // Init ns value
$s = 0; // Init ss value
foreach(explode("\n",$in_data) as $line){ // Divide text to lines
$info[] = explode(" ", $line); // Divide line to values and put them to array
if(in_array($info[0][4], $fa)) { // Check, if 4th array value (code) is in array
$ns = $ns (int) $info[0][5]; // plus to $ns, if yes
} else {
$s = $s (int) $info[0][5]; // plus to $s, if no
}
unset($info);
}
}
var_dump($ns, $s); // int(29) int(18)
Version 2. Do away with one level in $info as mentioned earlier:
foreach(explode("\n",$in_data) as $line){
$info = explode(" ", $line);
if(in_array($info[4], $fa)) {
$ns = $ns (int) $info[5];
} else {
$s = $s (int) $info[5];
}
}
Alternative version, regexp:
foreach(explode("\n",$in_data) as $line){
$info = preg_split('/\s{4,}/', $line); // Split when 4 or more spaces
if(in_array($info[3], $fa)) {
$ns = $ns (int) $info[4];
} else {
$s = $s (int) $info[4];
}
}
That way you don't get any "junk columns" :).
Edit: I think it was PHP 7.1 that introduced some more "strictness" regarding adding values of different types, strings numbers that is. A notice is issued, "A non well formed numeric value encountered". But if the string is cast/converted as a number before summing PHP will accept it. Casting can be done by adding (int)
in front of the string value. (Provided it contains an integer value, of course, otherwise it needs to be cast differently)