【问题标题】:Matching array elements to get an array element at another index匹配数组元素以获取另一个索引处的数组元素
【发布时间】:2010-04-02 18:20:17
【问题描述】:

我有一个用于生成 HTML 表单的 PHP 数组。 PHP 数组是这样的:

<?php
$vdb = array (
        array(  "Alabama",              275),
        array(  "Alaska",               197),
        array(  "Arizona",              3322));
?>

生成 HTML 表单的 PHP 如下。我需要将值作为状态的名称,因为我正在使用一些 AJAX 来显示用户选择了哪些状态。

<?php
    echo "<table border='1'><thead><tr><th></th><th>State</th><th>Contacts</th><th>Email</th></tr></thead>";
    for ($row = 0; $row < 42; $row++) {
        echo "<tr><td class='input_button'><input type='checkbox' name='vdb[]' value='".$vdb[$row][0]."' title='".$vdb[$row][1]."' /></td>";
        echo "<td>".$vdb[$row][0]."</td>";
        echo "<td>".$vdb[$row][1]."</td>";
    }
    echo "</table>";
?>

我要做的是,在提交表单时,使用用户选择的状态,循环遍历 PHP 数组并汇总所选状态的数字。所以如果我检查阿拉巴马州和阿拉斯加州,我想加上 275 + 197。

我认为这是可行的,但事实并非如此:

<?php
    $vendors = array();
    if (isset($_POST["vdb"])) {
        $vendors = $_POST["vdb"];
    }

    $ven_i = 0;
    $ven_j = 0;
    $ven_total = 0;
    foreach ($vendors as $value) {
        foreach ($vdb as $vdb_value) {
            if ($vendors[$ven_i] == $vdb[$ven_j][0]) {
                $ven_total += $vdb[$ven_j][1];                                   
            }
            $ven_j++;
        }
        $ven_i++;
    }
?>

然后 $ven_total 应该是我正在寻找的总数。然而,$ven_total 最终只是被选中的第一个复选框,它忽略了其余的复选框。我使用 AJAX 正确执行此操作,在前端显示总数,但我不知道如何将其传递给表单提交。我宁愿不使用 GET 和 URL 变量,因为用户可以在 URL 中输入一些内容并修改计数。知道我做错了什么,或者我能理解的更好的方法吗? (非常新手程序员。)

【问题讨论】:

  • $vdb 数组是如何构建的?是来自mysql_query 还是什么?是静态编码的吗?
  • 如果您从不使用 $value 或 $vdb_value 并且正在进行 index++ 调用,为什么要使用 foreach 而不是普通的 for?
  • @smotchkkiss $vdb 是一个静态数组,数字每隔几周/几个月手动更新一次。 @unholysampler 我想我可以使用 for,我使用的是 foreach 因为它会自动停止在数组的末尾,对吗?我不必担心迭代太多或太少。实际上,我想我可以使用 $value 而不是 $vendors[$ven_i]
  • 为什么不为每个项目使用键控数组而不是二元素数组?例如,array('Alabama' =&gt; 275) 而不是 array('Alabama', 275)?
  • 我实际上还有一个与数组关联的额外整数,只是想在这里为帖子简化它。所以阿拉巴马州实际上有 275 个联系人和 210 个电子邮件。有没有办法键两个项目? (就像我说的,对此很陌生。很高兴能到达我所到达的地方,但我遇到了很多砖墙。:P)感谢您的帮助。

标签: php arrays foreach


【解决方案1】:

这个答案最终会有几个不同的建议,但请耐心等待。 首先,使用列表作为数据结构会变得混乱,因为您最终会忘记索引 1 的实际含义。因此,由于您拥有的不仅仅是名称与值的配对,您可以尝试将其设为基本类并让您的代码更具可读性。

<?php
class State {
    public $name;
    public $contact_count;
    public $email_count;

    function __construct($name, $contact_count, $email_count) {
        $this->name = $name;
        $this->contact_count = $contact_count;
        $this->email_count = $email_count;
    }
}

$states = array (
    new State("Alabama", 275, 210),
    new State("Alaska", 197, 149),
    new State("Arizona", 3322, 2145));

$selected_vendors = array("Alabama", "Arizona");

$ven_total = 0;
foreach ($selected_vendors as $selected) {
    foreach ($states as $state) {
        if ($selected == $state->name) {
            $ven_total += $state->contact_count;                                   
        }
    }
}
echo $ven_total
?>

这仍然是你的代码刚刚清理了一些。循环和添加似乎工作正常。您是否已完成print_r($_POST) 以确保您以您期望的方式获得价值?您提到不想使用 GET,但 POST 可以像 GET 一样被欺骗,始终验证来自用户的输入。

【讨论】:

  • 感谢 unholysampler。我知道已经有几天了,但我刚刚回到这个项目,这个解决方案看起来比我现在拥有的要干净得多。我会试一试。是的,我需要验证这个表单,但是在让 jQuery 验证与 FormToWizard jQuery 插件一起工作时遇到了麻烦,我用来把这个东西变成一个向导。不过感谢您的帮助,我会测试一下!
  • 很高兴听到您能够理解我写的内容。如果它最终是正确的答案,请记住接受。
【解决方案2】:

为什么不用数字作为 $vdb 数组的键?

    $vdb = array (
            array( 275=>"Alabama" ),
            array( 197=>"Alaska" ),
            array( 3322=>"Arizona" )
    );

然后

$sum = array_intersect($vdb, $vendors);
$total = 0;
foreach ($sum as $key=>$value) {
   $total = $total+$key;
}
unset($key, $value, $sum);

array_intersect() 函数比较两个或多个数组,并返回一个包含第一个数组中的键和值的数组,前提是该值存在于所有其他数组中。

【讨论】:

  • 也许我应该在原始帖子中包含这个,但数组实际上看起来像这样: $vdb = array ( // State # Email array( "Alabama", 275, 210), array( "阿拉斯加", 197, 149), array("亚利桑那", 3322, 2145));
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 2021-11-24
  • 2018-12-24
  • 2021-08-15
  • 1970-01-01
  • 2018-11-21
相关资源
最近更新 更多