Как удалить / заменить определенные символы из ключей и значений в массиве? - PullRequest
0 голосов
/ 19 сентября 2018

Моя цель - удалить группу символов из ключей одномерного массива и другую группу символов из значений этого же массива.Пример:

$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 пример : разрешает замену значений по ссылке, но если ятакже передать ключ по ссылке в параметрах обратного вызова, то же самое не происходит;
  • array_replace: ключи также не изменены;
  • array_map пример : создание копии массива, но необходима предварительная обработка array_keys($arr).

Поэтому моя цель - выполнить все замены за один раз, избегая повторного использования функций PHP, которыезацикливать массив несколько раз.

Я поместил ответ в этот же поток с моей попыткой, которая работает, но я не мог найти способ избежать unset($arr[$invalid_key]) (естьесть ли другой способ «изменить» сам ключ, не удаляя его?) или выполнить только одно присваивание, если строки ключа и значения нуждаются в замене.

Есть ли уже функция PHP, которая делает это?Т.е. однопетлевое, мало условий, минимум замен и в целом более эффективно?Если нет, как я могу улучшить мой?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Нет, в 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.
}
0 голосов
/ 19 сентября 2018

Без использования библиотечных функций :

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 на 3v4l.org .

...