【问题标题】:Checking Values in PHP Arrays with in_array(); [duplicate]使用 in_array() 检查 PHP 数组中的值; [复制]
【发布时间】:2012-10-03 08:35:38
【问题描述】:

可能重复:
Implode array with “, ” and add “and ” before last item

我正在自定义一个 WordPress 主题,并且我在管理员的用户个人资料页面中创建了一些复选框,确切地说是 3 个。当用户选中每个框时,该框的值会保存在一个名为 $goals 的数组中,当他们保存他们的个人资料时。这一切都很好。

在模板页面上,我正在对如何根据用户选择的目标显示某些内容进行一些测试,因此我创建了以下代码来检查数组是否包含它自己的每个值,然后是目标的组合一起,然后根据这些选择回显特定内容。它工作得很好,但我觉得代码臃肿并且可以简化。这是我一直希望用我的代码做的事情。我非常感谢您对如何用更少的代码实现相同结果的想法。谢谢。

$goals = get_user_meta( $userID, 'goals', $single );

if (in_array('Weight Loss', $goals, true) && !in_array('Improve Fitness', $goals, true) && !in_array('Improve Health', $goals, true)) {
    echo 'Weight Loss';
} elseif (in_array('Improve Fitness', $goals, true) && !in_array('Weight Loss', $goals, true) && !in_array('Improve Health', $goals, true)) {
    echo 'Improve Fitness';
} elseif (in_array('Improve Health', $goals, true) && !in_array('Improve Fitness', $goals, true) && !in_array('Weight Loss', $goals, true)) {
    echo 'Improve Health';
} elseif (in_array('Weight Loss', $goals, true) && in_array('Improve Fitness', $goals, true) && !in_array('Improve Health', $goals, true)) {
    echo 'Weight Loss and Improve Fitness';
} elseif (in_array('Weight Loss', $goals, true) && !in_array('Improve Fitness', $goals, true) && in_array('Improve Health', $goals, true)) {
    echo 'Weight Loss and Improve Health';
} elseif (!in_array('Weight Loss', $goals, true) && in_array('Improve Fitness', $goals, true) && in_array('Improve Health', $goals, true)) {
    echo 'Improve Fitness and Improve Health';
} elseif (in_array('Weight Loss', $goals, true) && in_array('Improve Fitness', $goals, true) && in_array('Improve Health', $goals, true)) {
    echo 'Weight Loss, Improve Fitness and Improve Health';
} else {
    echo 'Nothing set';
}

【问题讨论】:

  • @deceze 但这并不直接处理空数组;即它不会在具有空字符串的数组和空数组之间消除歧义。
  • 然后array_filter您的数组之前或以其他方式确保其中没有空字符串,然后为空数组创建一种特殊情况。

标签: php arrays wordpress


【解决方案1】:

以人类可读的形式表示目标列表:

if (count($goals) > 1) {
    echo join(', ', array_slice($goals, 0, -1)) . ' and ' . end($goals);
} elseif ($goals) {
    echo $goals[0];
} else {
    echo "Nothing set";
}

根据您拥有的项目数量,代码将返回 "X" / "X and Y" / "X, Y and Z"

如果有多个项目,它会执行以下操作:

  1. 使用 array_slice() 并在它们之间添加逗号 - 使用 join(),将项目添加到但不包括最后一个项目。
  2. 添加单词" and "和最后一项的值。

要将$goals 数组缩小到您提到的那些项目:

$goals = array_intersect(array('Weight Loss', 'Improve Fitness', 'Improve Health'), $goals);

它会删除除您感兴趣的值之外的所有值,在您的情况下只有其中三个。不过,根据您的情况,您可能不需要此代码。

【讨论】:

  • 感谢您的回复。我真的不明白这里发生了什么,因为我不是 PHP 专家,但我会试一试,看看会发生什么,不过我想更详细地了解你的答案。给了我一些思考和研究的起点。谢谢。
  • @GarethDaine 更新了答案,希望现在更有意义。
  • 只是想。我的代码中的 echo 语句只是占位符,用于显示我的 if 语句正在运行的代码将基于选择的 WordPress 自定义帖子类型内容。也就是说,“array_slice”函数是如何影响的?另外,如果我需要知道代码是返回 Y 和 Z 还是 X 和 Z,该怎么办?
  • @GarethDaine 好吧,这个问题不是很清楚,我认为您的原始代码已经在工作,所以我写了一个等价的。
  • 该代码确实有效,抱歉。它正是我想要的。但是通过您的解释,您的代码似乎只返回您提到的“X”/“X 和 Y”/“X、Y 和 Z”,这不是我的代码所做的。另外,我并不是要回显已选择的内容,我只是想找出已选择的内容,然后根据该内容显示内容。谢谢。
【解决方案2】:

如果您不想像示例所建议的那样简单地连接字符串,则该代码的更精简版本将是这样的:

sort($goals);

switch ($goals) {
    case array('Weight Loss') :
        ...
        break;

    case array('Improve Fitness', 'Weight Loss') :
        ...
        break;

    ...
}

这里重要的是两个数组中的元素顺序相同,因此最初的sort 和比较元素按字母顺序排列。

话虽如此,但必须有比处理所有可能的排列更好的方法来处理这个问题,因为随着您添加更多选项,它会呈指数增长。您通常应该遍历目标集合,为每个目标做一些事情,然后输出一些汇总值:

$output = array();

foreach ($goals as $goal) {
    switch ($goal) {
        case 'Weight Loss' :
            $output[] = 'I want to lose weight.';
            break;

        case 'Improve Fitness' :
            $output[] = ...
            break;

        ...
    }
}

echo join("\n", $output);

有了一个非常明智的基于 OOP 的结构,其中每个目标都被定义为一个单独的对象,这看起来更像:

$output = array();

foreach ($goals as $goal) {
    $output[] = $goal->objectiveDescription();
}

echo join("\n", $output);

换句话说,你解决问题的方式是不够的。但是,如果不知道您实际上想做什么,就很难提出建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多