【问题标题】:How to remove/replace certain characters from both keys and values in an array?如何从数组中的键和值中删除/替换某些字符?
【发布时间】:2019-02-23 12:32:50
【问题描述】:

我的目标是从 一维 数组的键中删除一组字符,并从同一数组的值中删除另一组字符。示例:

$arr = [
  'a' => 'Letter A!',
  '`b`' => 'Letter B w/quotes...',
  ' c ' => 'Letter C w/spaces?',
  ' -_-`d`- _ - ' => 'Letter D w/all?!...'
];
$invalid_keys_chars = ['`',' ','_','-'];
$invalid_vals_chars = ['!','?','.'];

// GOAL: looking for something like this function
array_del_invalid($arr, $invalid_keys_chars, $invalid_vals_chars));
var_export($arr);
// ---> output
// array (
//   'a' => 'Letter A',
//   'b' => 'Letter B w/quotes',
//   'c' => 'Letter C w/spaces',
//   'd' => 'Letter D w/all'
// )

我首先研究了常见的 PHP 函数:

  • array_walk example:允许通过引用替换值,但如果我也在回调参数中通过引用传递键,则不会发生同样的情况;
  • array_replace:键也没有修改;
  • array_map example:构造一个数组的副本,但之前对array_keys($arr) 的处理是必要的。

所以我的目标是一次性执行所有替换,避免重复使用循环数次数组的 PHP 函数。

我尝试使用answer on this same thread 放置了一个answer on this same thread,这是有效的,但我无法找到避免unset($arr[$invalid_key]) 的方法(是否有另一种方法可以在不删除它的情况下“更改”密钥本身?)或做如果键和值字符串都需要替换,则只分配一个。

是否已经有一个 PHP 函数可以做到这一点? IE。单循环,很少的条件,最少的替换和整体更高效?如果没有,我该如何改进我的?

【问题讨论】:

    标签: php arrays replace str-replace array-key


    【解决方案1】:

    不,PHP 中无法通过引用修改数组键。您只能添加和删除键。

    即使array_change_key_case 也会创建一个新数组而不是修改原始数组。

    您可以在函数中创建一个新数组并返回新数组。然后你可以用干净的版本覆盖你原来的数组变量。

    <?php
    function deleteInvalid($dirty, $ikc = [], $ivc = []) {
        $clean = [];
        foreach ($dirty as $key => $val) {
            $cKey = str_replace($ikc, '', $key);
            $cVal = str_replace($ivc, '', $val);
            $clean[$cKey] = $cVal;
        }
        return $clean;
    }
    
    $dirty = deleteInvalid($dirty);
    var_dump($dirty);
    

    你不需要测试 str_replace 之后值的变化,因为如果它没有变化,它会是一样的。当然,除非您的数组包含的不仅仅是字符串……在这种情况下,您应该在修改之前测试值的类型。

    <?php
    if (is_string($val)) {
        // do something with the string.
    }
    

    【讨论】:

    • 谢谢。是的,我想当使用新数组而不是修改输入数组时,它会变得更简单、更快。
    【解决方案2】:

    不使用array library functions:

    function array_del_invalid(&$a, $ikc = [], $ivc = []) {
      if(! empty($ikc) || ! empty($ivc)) {
        foreach ($a as $k => $v) {
          $treated_key = str_replace($ikc, '', $k);
          $treated_val = str_replace($ivc, '', $v);
          if($k !== $treated_key) {
            unset($a[$k]);
            $a[$treated_key] = $v;
          }
          if($v !== $treated_val) {
            $a[$treated_key] = $treated_val;
          }
        }
      }
    }
    $arr = [
      'a' => 'Letter A!',
      '`b`' => 'Letter B w/quotes...',
      ' c ' => 'Letter C w/spaces?',
      ' -_-`d`- _ - ' => 'Letter D w/all?!...'
    ];
    $original_arr = $arr;
    $invalid_keys_chars = ['`',' ','_','-'];
    $invalid_vals_chars = ['!','?','.'];
    array_del_invalid($arr, $invalid_keys_chars, $invalid_vals_chars);
    var_export($arr);
    // ---> output
    // array (
    //   'a' => 'Letter A',
    //   'b' => 'Letter B w/quotes',
    //   'c' => 'Letter C w/spaces',
    //   'd' => 'Letter D w/all'
    // )
    
    // only keys replacement
    $arr = $original_arr;
    array_del_invalid($arr, $invalid_keys_chars);
    var_export($arr);
    // array (
    //   'a' => 'Letter A!',
    //   'b' => 'Letter B w/quotes...',
    //   'c' => 'Letter C w/spaces?',
    //   'd' => 'Letter D w/all?!...',
    // )
    

    在线运行@array_del_invalid on 3v4l.org

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 2019-03-04
      • 2021-01-23
      相关资源
      最近更新 更多