【问题标题】:PHP array keeps adding a seperate key-value instead of adding to existing keyPHP数组不断添加单独的键值而不是添加到现有键
【发布时间】:2012-09-27 22:02:24
【问题描述】:

我正在尝试订购我的阵列。我的第一个数组将具有值字符串值,其中很少有相同的值现在我想知道每个值有多少,并将其添加到新数组中作为键和值它现在出现在第一个数组中的次数我开始这样做,但我遇到了一个错误。

最后一个条目而不是被计数器添加额外。

我尝试了 while/for/foereach 相同的结果。

代码:

<?php
 function add_fit($fitting)
   {
        // Save raw fit
        $eft = $fitting;

        // Clean for import
        $fit = trim($fitting);
        $lines = explode("\n", $fit);
        $lines = array_filter($lines, 'trim');

        // Split first line for name and type
        $details = str_replace('[', '', $lines[0]);
        $details = str_replace(']', '', $details);
        $split_details = explode(', ', $details);

        $ship = $split_details[0];
        $name = $split_details[1];

        foreach ($lines as $line => $module) {
            if(strstr($module, '[empty '))
            {
                unset($lines[$line]);
            }
        }

        $all = array();
        foreach ($lines as $index => $segment) {
            array_push($all, $segment);
        }

        $modules = array();
        for($i = 1; $i < count($all); $i++)
        {
            if(isset($modules[$all[$i]]))
            {
                $modules[$all[$i]] = $modules[$all[$i]]+1;
            } else {
                $modules[$all[$i]] = 1;
            }
        }

        var_dump($modules);

   }

/*
The $fitting is as follows:

[Thrasher, Buffer Thrasher]
Gyrostabilizer II
Gyrostabilizer II

Small F-S9 Regolith Shield Induction
Small F-S9 Regolith Shield Induction
1MN MicroWarpdrive I

280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
280mm Howitzer Artillery II
[empty high slot]

Small Ancillary Current Router I
Small Ancillary Current Router I
Small Ancillary Current Router I


And the method returns:
  'Gyrostabilizer II'                    => int 2
  'Small F-S9 Regolith Shield Induction' => int 2
  '1MN MicroWarpdrive I'                 => int 1
  '280mm Howitzer Artillery II'          => int 7
  'Small Ancillary Current Router I'     => int 2
  'Small Ancillary Current Router I'     => int 1


While it should return:
  'Gyrostabilizer II'                    => int 2
  'Small F-S9 Regolith Shield Induction' => int 2
  '1MN MicroWarpdrive I'                 => int 1
  '280mm Howitzer Artillery II'          => int 7
  'Small Ancillary Current Router I'     => int 3   <-- Like this
*/

?>

【问题讨论】:

  • 你的第一句话没有意义..来点标点符号怎么样?
  • 没有单独的独立应用程序。我还需要一份参数的副本,以便稍后传递。

标签: php arrays foreach


【解决方案1】:

您的输入中必须有一些非打印字符,因为哈希不能具有具有多个值的相同键(这是您的输出显示的 - Small Ancillary Current Router I 的两个键,它们必须不同,因为它们有不同的价值观……)

var_dump(array_keys($modules)) 节目是什么?

解决方案是更好地清理您的输入 - 看起来您应该在清理部分添加一些内容。 . .可能是like this to strip UTF,或者如果这是您输入的最后一行,则其中可能有一个 EOF 字符。 . .

编辑:在您的 cmets 中,var_dump 输出为:

5 => string 'Small Ancillary Current Router I' (length=33) 
6 => string 'Small Ancillary Current Router I' (length=32)

请注意,一个是 33,另一个是 32,这意味着非打印字符会导致差异。删除所有非打印字符的霰弹枪方法是described here。在您的代码中实现:

    $all = array();
    foreach ($lines as $segment) {
        $all[] = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $segment);
    }

【讨论】:

  • 试过了,还是同样的问题。
  • 5 => string 'Small Ancillary Current Router I' (length=33) 6 => string 'Small Ancillary Current Router I' (length=32) 它们是不同的长度,假设有不可打印以前的字符,但我无法以任何方式删除它们,我尝试 str 替换、修剪、perg_match 等。
  • 您在 array_filter 中用作回调的 trim 函数是什么样的?
  • 它只是再次调用 trim 来删除任何多余的 \r 字符。
  • 我还是一样。唯一的方法是,如果在我的输入中我在最后添加另一行文本,我不会得到两个名称相同的键。然后我得到两个 Small Ancil .. 在一个键和值下说 3 应该是,但我也有另一个无意义的条目
【解决方案2】:

您可能应该使用array_key_exists() 而不是isset。原因可见this SO question

无论哪种方式,您都有一些导致问题的空格。尝试在以下行中添加修剪,它应该可以工作:

foreach ($lines as $index => $segment) { 
    array_push($all, $segment); 
} 

改为:

foreach ($lines as $index => $segment) { 
    array_push($all, trim($segment)); 
} 

顺便说一句:o7 安全飞行 ;-)

更新:这是我用于测试的代码:

<!DOCTYPE html>
<html>

<head>
</head>
<body>
<?php 

$whatever = "[Thrasher, Buffer Thrasher] 
Gyrostabilizer II 
Gyrostabilizer II 

Small F-S9 Regolith Shield Induction 
Small F-S9 Regolith Shield Induction 
1MN MicroWarpdrive I 

280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
280mm Howitzer Artillery II 
[empty high slot] 

Small Ancillary Current Router I 
Small Ancillary Current Router I 
Small Ancillary Current Router I";

echo '<pre>';
print_r(add_fit($whatever));
echo '</pre>';


 function add_fit($fitting) 
   { 
        // Save raw fit 
        $eft = $fitting; 

        // Clean for import 
        $fit = trim($fitting); 
        $lines = explode("\n", $fit); 
        $lines = array_filter($lines, 'trim'); 

        // Split first line for name and type 
        $details = str_replace('[', '', $lines[0]); 
        $details = str_replace(']', '', $details); 
        $split_details = explode(', ', $details); 

        $ship = $split_details[0]; 
        $name = $split_details[1]; 

        foreach ($lines as $line => $module) { 
            if(strstr($module, '[empty ')) 
            { 
                unset($lines[$line]); 
            } 
        } 

        $all = array(); 
        foreach ($lines as $index => $segment) { 
            array_push($all, trim($segment)); 
        } 

        $modules = array(); 
        for($i = 1; $i < count($all); $i++) 
        { 
            if(isset($modules[$all[$i]])) 
            { 
                $modules[$all[$i]] = $modules[$all[$i]]+1; 
            } else { 
                $modules[$all[$i]] = 1; 
            } 
        } 

        return $modules; 

   } 

?>
</body>
</html>

【讨论】:

  • 嘿,伙计,我尝试了 array_key_exists() 并修剪了 $segment 但这不是最后一个键中的前两个模块的长度为 33,而最后一个模块的长度为 32,但它们显示的所有内容都相同。奇怪的是我修剪掉了所有的\r和\n。也可以安全飞行 o7
  • @kellax:我在我的测试台上尝试了您的代码,并添加修剪以您想要的方式修复了输出。除了编码问题/差异之外,不确定您的设置可能有什么不同。您使用 apache、IIS 等?什么版本的 PHP?
  • 我在 PHP 5.4.3 中使用 WAMP,页面编码设置为 utf8 我也试过 preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $segment ) 当我在 $modules 数组上执行 var_dump 时,我得到最后一个键的长度为 32,而在它之前的长度为 33,因此在某处没有被删除的不可打印字符。
  • 我还假设输入的 $fitting 值是一个字符串。
  • $fiting 是直接来自
猜你喜欢
  • 1970-01-01
  • 2016-03-28
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 2013-06-22
相关资源
最近更新 更多