【问题标题】:Parsing input text to array and sum values将输入文本解析为数组和求和值
【发布时间】:2021-12-16 02:11:58
【问题描述】:

你好 :) 我被困在我的迷你应用程序开发中。我有以下文字,从第 3 方网页复制:

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

我需要将其解析为以下格式: $s = 10, $ns = 11, $bs = 26,点赞:

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

我现在的代码如下:

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
  }
}

但它似乎没有将线切割成数组。它只是向我显示线条,而不是划分为数组。我使用的是 Summernote 文本编辑器,它以行的形式发送数据。

【问题讨论】:

  • 你的代码需要大量的cmets来解释,我还是一个都看不懂。
  • 我认为错误在"/n"。我想你打算使用"\n",一个反斜杠而不是一个正斜杠?
  • 也许有标签标志?尝试用"\t" 炸开$line。
  • 不,不是制表符,而是 4 个空格。已检查。
  • @Serique 好吧.. 确实如此。的种类 ;)。不过,您需要考虑 $info 在您的代码中的外观。正如其他人已经说过的那样,$info[]=... 导致它的深度为 2 级,而不是您的代码所期望的 1 级。如果您将其更改为$info = ...,它应该会更好。此外,您实际上并不需要 unset(),除非您稍后在代码中使用 $info。

标签: php arrays parsing textarea


【解决方案1】:

因为您使用的是$info[] = ...,所以您会得到一个 2 级深度数组,而不是代码所期望的 1 级。 $info[] = ... 基本上意味着“将右侧添加到 $info 作为 one 元素”。因此,如果右侧是一个字符串并且 $info 在你得到[0 => "my string"] 之前是空的。如果右边是一个数组,你会得到[0 => [0 => "my", 1 => "array"]]。

你明白我在说什么吗?您的代码将 one 元素添加到 $info,仅此而已。因此,要访问 $info 中的任何内容,第一部分必须是 $info[0]。但是代码会查找第 4 和第 5 个元素,但它们永远不会出现。另一方面,如果您要查找 inside 第一个元素的第 4 个元素。也就是说,$info[0] 是第一个元素,然后是第 4 个元素:$info[0][4],然后你会得到你想要的。

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)

第 2 版。如前所述,取消 $info 中的一级:

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];
  }
}

替代版本,正则表达式:

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];
  }
}

这样你就不会得到任何“垃圾列”:)。

编辑:我认为是 PHP 7.1 在添加不同类型的值时引入了更多“严格性”,即字符串 + 数字。发出通知,“遇到格式不正确的数值”。但是如果字符串在求和之前被转换/转换为数字,PHP 将接受它。可以通过在字符串值前面添加(int) 来完成转换。 (当然前提是它包含一个整数值,否则需要进行不同的转换)

【讨论】:

  • 此代码无法按预期工作。它不会使我可以使用数组。每个下一个数组元素的编号都会增加。第一排 1-5,第二排 6-10 以此类推。但是您的 previos 版本,当 $info 没有 [] 时几乎可以按预期工作
  • @Serique 你是说第一个版本?你是对的,正在修复。
  • 复制粘贴太多。谢谢,更正。
  • @Serique 这很奇怪,在我的测试运行中它的总和是正确的。
猜你喜欢
  • 2013-12-05
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
相关资源
最近更新 更多