Использование str_replace и foreach для удаления символов из многомерного массива: проблемы с областью действия?

У меня есть массив ($arr):

[0] => Array
    (
        [sv_317] => 1,650
        [sv_318] => 1,254

    )


[1] => Array
    (
        [sv_317] => 1,580
        [sv_318] => 1,580

    )

Я пытаюсь использовать эти значения элементов как числовые значения, поэтому мне нужно удалить любые нечисловые символы (запятые в приведенном выше примере).

Для этого я использую:

foreach($arr as $k=>$v)
    {       
    $v[sv_317] = str_replace(",", "", $v[sv_317]);
    $v[sv_317] = preg_replace('/\s+/', '', $v[sv_317]);
    $v[sv_318] = str_replace(",", "", $v[sv_318]);
    $v[sv_318] = preg_replace('/\s+/', '', $v[sv_318]);

    echo "318 :".$v[sv_318];
    echo "317 :".$v[sv_317];
    }

Отголоски нужны только для того, чтобы проверить, что он делает то, что я задумал, и, конечно же, они печатают значения элементов без запятых и пробелов.

Однако это не привело к возможности численного использования элементов, поэтому я протестировал массив с помощью print_r($arr); сразу после вышеуказанного цикла, и элементы массива не изменились (т.е. все еще содержат запятые.

Есть ли здесь проблема масштаба? Если да, то как я могу удалить запятые навсегда?

Большое спасибо.


person Gideon    schedule 24.06.2013    source источник


Ответы (2)


Цикл foreach не работает с самим массивом. Он работает с копией массива. Итак, когда вы делаете print_r($arr), отображается исходный массив. Фактический массив $arr не изменяется.

Из документации PHP foreach:

Чтобы иметь возможность напрямую изменять элементы массива внутри цикла, перед $value следует поставить &. В этом случае значение будет присвоено по ссылке.

<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // break the reference with the last element
?>

Посмотрите этот пост SO, чтобы понять, как на самом деле работает foreach: Как на самом деле работает PHP foreach?

Надеюсь, что это ответ на ваш вопрос :)

person Amal Murali    schedule 24.06.2013
comment
Ой! Каков наилучший способ редактирования массива таким образом? - person Gideon; 25.06.2013
comment
Создать новый (пустой) массив (перед циклом) и добавить (втолкнуть) в него измененные значения (внутри цикла)? - person sinisake; 25.06.2013

Поскольку вы пытаетесь изменить $v, это должна быть ссылочная переменная, например:

foreach($arr as $k => &$v) {       
  $v[sv_318] = str_replace(",", "", $v[sv_318]);
}

... Но в вашем коде есть еще что исправить:

  • Вы должны unset($v) в конце, чтобы последующий код не вел себя странно
  • Индексы массива должны быть заключены в кавычки, поскольку они являются строковыми литералами.
  • Я предпочитаю strtr() вместо str_replace(), так как соответствие понятнее:

.

foreach($arr as $k => &$v) {
  $v['sv_318'] = strtr( $v['sv_318'], array(','=>'') );
}; unset($v);

Кроме того, для обработки любого количества значений в $v я бы использовал другой foreach:

foreach ($arr as $key => &$subarr) {       
  foreach ($subarr as $subkey => &$val) {       
    $val = strtr( $val, array(','=>'') );
  }; unset($val);
}; unset($subarr);
person wst    schedule 24.06.2013