【问题标题】:Replace repeating value with zero in PHP string用零替换 PHP 字符串中的重复值
【发布时间】:2020-12-05 13:03:11
【问题描述】:

以下是代码

<?php
$id ="202883-202882-202884-0";
$str = implode('-',array_unique(explode('-', $id)));
echo $str;
?>

结果是

202883-202882-202884-0

对于$id ="202883-202882-202882-0";,结果是202883-202882-0

我想用零替换重复值,这样结果应该像202883-202882-0-0,而不是直接删除它。

对于$id ="202883-0-0-0";,结果应该是202883-0-0-0。零不应被替换,允许重复的零。 我该如何存档?

更多信息:
我想替换每个重复的数字。因为这是一个产品比较网站。最多只能有 4 个数字。每个将是一个 6 位数字或单个数字零。全零表示未选择任何产品。一个 6 位数字和 3 个零表示,选择一个产品和 3 个空白。

每个 6 位数字都会从数据库中收集数据,我不想让用户多次输入相同的数字(仅当数字与 URL 一起手动添加时才会发生。)。

更新:我知道我的问题不清楚,可能是我的英语很差。 这里有更多解释,这个功能是针对智能手机比较网站的。 URL 格式为sitename.com/compare.html?id=202883-202882-202889-202888。 所有三个数字都是不同的智能手机(它们的数据库产品 ID)。 我不想让用户输入相同的产品 ID,如 id=202883-202882-202882-202888。它不会在网站中显示两个202882结果,但会引起一些小问题。 URL 不变,但内部 PHP 代码应将其视为id=202883-202882-202888-0。 重复项应替换为零并添加到末尾。 将只有 4 个数字,用“-”分隔。 以下示例可能会清除云!

如果pid=202883-202882-202889-202888,结果应该是202883-202882-202889-202888 如果pid=202883-202883-202883-202888 结果应该是202888-0-0-0 如果pid=202883-202882-202883-202888 结果应该是202883-202882-202888-0 如果pid=202882-202882-202882-202882 结果应该是202882-0-0-0

我希望字符串中只允许 6 位数字或单个数字零。

如果pid=rgfsdg-fgsdfr4354-202883-0,结果应该是202883-0-0-0 如果pid=fasdfasd-asdfads-adsfds-dasfad 结果应该是0-0-0-0 如果pid=4354-45882-445202882-202882 结果应该是202882-0-0-0

这对我来说太复杂了,我知道有聪明的人可以比我更有效地做到这一点。

【问题讨论】:

  • 你想替换每个重复的数字还是只替换连续的重复?
  • 我也想听听皮兰的问题的回答。蒂姆的回答假设重复项总是连续的。如果它们不是连续的,蒂姆的答案会让你失望。
  • 也许你们俩都应该停止多次指出同一个(可能的)边缘情况:-)
  • 我认为这个问题不清楚(你可以这样投票),更像是一个 XY 问题。我在之前的评论中表达了我对数据结构的担忧。 @Funk
  • @mickmackusa 我会选择“不清楚”,但我很确定它会是锤子。无论哪种方式,我都会编辑此评论。编辑:好的,它确实采取了我不清楚的投票。但可以肯定的是,如果我投票为“不工作”,那将是一个骗局。我以前也遇到过。

标签: php


【解决方案1】:

你可以做一个array_unique(保留键),然后用0填补空白。按键排序,你就完成了:)

数组上的+unify 数组,但优先考虑左边的数组。

代码

$input = "0-1-1-3-1-1-3-5-0";
$array = explode('-', $input);
$result = array_unique($array) + array_fill(0, count($array), 0);
ksort($result);

var_dump(implode('-',$result));

代码(v2 - 由 mickmackusa 建议)- 更短且更易于理解

填充输入数组大小的数组。并用来自array_unique 的剩余值替换。不需要ksort0s 将被替换为 array_unique 的保留键。

$input = "0-1-1-3-1-1-3-5-0";
$array = explode('-', $input);
$result = array_replace(array_fill(0, count($array), 0), array_unique($array));
var_export($result);

工作example

输出

string(17) "0-1-0-3-0-0-0-5-0"

工作example

参考

  • ksort - 按键排序
  • array_fill - 生成一个以一定长度的0 填充的数组

【讨论】:

    【解决方案2】:

    这是另一种方法。

    $id = "202883-202882-202882-0-234567-2-2-45435";
    

    从字符串中,您可以根据分隔符将字符串分解为数组,在本例中为'-'/

    $id_array = explode('-', $id);
    

    然后我们可以遍历数组,对于我们找到的每个唯一条目,我们可以将它存储在另一个数组中。因此,我们在搜索数组时正在构建一个数组。

    $id_array_temp = [];
    // Loop through the array
    foreach ($id_array as $value) {
        if ( in_array($value, $id_array_temp)) {
            // If the entry exists, replace it with a 0
            $id_array_temp[] = 0;
        } else {
            // If the entry does not exist, save the value so we can inspect it on the next loop.
            $id_array_temp[] = $value;
        }
    }
    

    在此操作结束时,我们将得到一个唯一值数组,其中所有重复值都替换为 0。

    要重新创建字符串,我们可以使用 implode...

    $str = implode('-', $id_array_temp);
    echo $str;
    

    重构这个,使用三元来替换 If,else...

    $id_array = explode('-', $id);
    $id_array_temp = [];
    foreach ($id_array as $value) {
        $id_array_temp[] = in_array($value, $id_array_temp) ? 0 : $value;
    }
    $str = implode('-', $id_array_temp);
    echo $str;
    

    输出是

    202883-202882-0-0-234567-2-0-45435
    

    【讨论】:

      【解决方案3】:

      这似乎是经典的XY Problem

      基本操作只需:

      1. 用连字符分隔字符串中的子字符串。
      2. 验证每个子字符串中的字符格式是否正确,并且对于集合是唯一的。
      3. 只对符合条件的价值采取有意义的行动。

      您知道,当您真正需要验证输入数据时,替换/清理任何东西没有任何好处。在您的输入中添加零只会在以后创建更多工作。

      简而言之,您应该使用类似于此流程的直接方法:

      if (!empty($_GET['id'])) {
          $ids = array_unique(explode('-', $_GET['id']));
          foreach ($ids as $id) {
              if (ctype_digit($id) && strlen($id) === 6) {
              // or: if (preg_match('~^\d{6}$~', $id)) {
                  takeYourNecessaryAction($id);
              }
          }
      }
      

      【讨论】:

      • 我从来没有时间测试答案。我今天将测试所有这些并标记答案。请检查问题中添加的其他详细信息。
      • 如果您的应用程序无论如何都会在连字符上爆炸,那么使用正则表达式执行清理是没有意义的。如果您的脚本只对符合条件的数字采取有意义的操作,那么用零替换输入数据中的子字符串是没有意义的。
      • 如果字符串检测到 6 位数字或单个数字零,它将在操作前工作。但如果它检测到其他任何东西,则不会显示任何数据。但有些设计元素不能正常工作。
      • 那么看来,你需要修复这个后面的脚本。同样,这是一个 XY 问题。你有级联问题要解决。这通常表明您需要重构应用程序的某些部分,使其更直接和更有目的性。编写 hacky 代码以适应 hacky 代码最终会将您的代码库变成您自己不想维护的垃圾——更不用说其他会看到您的代码的开发人员了。
      • 感谢您的宝贵时间。可能是XY问题!我只是想通过从字符串中删除不需要的字符来避免错误。您建议修复该错误?这是可以避免的!这 4 个数字可以轻松管理,这 4 个产品 ID 用于脚本的多个部分。我认为只修复一个字符串而不是多个区域会更容易?
      猜你喜欢
      • 2017-04-03
      • 1970-01-01
      • 2021-03-24
      • 2011-10-10
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多