Array_filter с модификацией элемента

Я пытаюсь создать чистый массив из строки, которую определят мои пользователи. Строка может содержать недействительные идентификаторы, пробелы и т. д. Я проверяю элементы с помощью объекта значения в функции обратного вызова для array_filter.

$definedIds = "123,1234,1243, 12434 , asdf"; //from users panel

$validIds = array_map(
    'trim',
    array_filter(
        explode(",", $definedIds),
        function ($i) {
            try {
                new Id(trim($i));
                return true;
            } catch (\Exception $e) {
                return false;
            }
        }
    )
);

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

ПРИМЕЧАНИЕ. Я также мог бы вызвать array_map в первом параметре array_filter, но в любом случае я бы дважды перебирал массив.

В качестве небольшого предложения не заставляйте конструктор бросать, а вместо этого используйте статически определенный Id.isValidId(input), который вы можете вызывать, поэтому вам не нужно брать на себя выделение памяти, модификацию таблицы символов и сборку мусора. Вы ничего не делаете с создаваемым объектом Id, поэтому, если вы используете его только для проверки правильности идентификатора, сделайте эту функцию специальной функцией, которую вы можете вызвать.

Mike 'Pomax' Kamermans 01.05.2018 15:50

каков ваш ожидаемый результат?

Always Sunny 01.05.2018 15:52

почему бы вам не использовать str_replace для удаления пробелов перед отображением массива?

mim. 01.05.2018 15:55

@BeingSunny, это [123,1234,1243,12434]

CarlosAS 01.05.2018 15:57

@mim. это хорошая идея для этого конкретного случая, но все еще интересно, есть ли функция, использующая обратный вызов для заполнения возвращаемого массива

CarlosAS 01.05.2018 15:59

@CarlosAS, тогда вы можете попробовать array_walk_recursive.

mim. 01.05.2018 16:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
6
1 531
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это зависит от того, заботитесь ли вы о производительности. Если вы это сделаете, не используйте map + filter, а используйте простой цикл for и манипулируйте своим массивом на месте:

$arr = explode(',', $input);

for($i=count($arr)-1; $i>=0; $i--) {
  // make this return trimmed string, or false,
  // and have it trim the input instead of doing
  // that upfront before passing it into the function.
  $v = $arr[$i] = Id.makeValid($arr[$i]);

  // weed out invalid ids
  if ($v === false) {
    array_splice($arr, $i, 1);
  }
}

// at this point, $arr only contains valid, cleaned ids

Конечно, если это несущественный код, то двойная обрезка В самом деле не повлияет на производительность, но вы все равно можете все исправить:

$arr = explode(',', $input);
$arr = array_filter(
  array_map('Id.isValidId', $arr),
  function ($i) {
    return $i !== false;
  }
);  

В этом примере мы отображаем первый, используя эту функцию, поэтому мы получаем массив идентификаторов и значений false, а затем мы фильтруем его, чтобы все, что false, было выброшено, вместо того, чтобы сначала фильтровать, а затем отображать.

(В обоих случаях код, отвечающий за проверку действительности, находится в классе Id, и он либо возвращает очищенный идентификатор, либо false)

На самом деле вы можете сделать это по-другому, но на вашем месте я бы сделал это так. Здесь я просто использовал только один отделка

<?php
$definedIds = "123,1234,1243, 12434 , asdf"; //from users panel
function my_filter($b){
    if (is_numeric($b)){
        return true;
    }
}
print '<pre>';
$trimmed = array_map('trim',explode(',',$definedIds));
print_r(array_filter($trimmed,my_filter));
print '</pre>';
?>

Вывод программы:

Array
(
    [0] => 123
    [1] => 1234
    [2] => 1243
    [3] => 12434
)

ДЕМО:https://eval.in/997812

Это тот же код моего вопроса, вы только что назвали функцию обратного вызова и удалили проверки объекта значения ...

CarlosAS 01.05.2018 16:46

@CarlosAS: P Да, ты ri8, я просто подсознательно опубликовал ту же логику, что и ты. Смотрите мою правку сейчас Я использовал только один раз отделка внутри array_map ()

Always Sunny 01.05.2018 19:40

Другие вопросы по теме