3

Assume I have an array:

$origin = ['value1', 'value2', 'value3', 'value4'];

and a replace map array:

$replace_map = [
    'value1' => 'replace1',
    'value2' => 'replace2',
    'value8' => 'replace8',
];

I want to replace the $origin array and expect the result to be:

$result = myReplace($origin, $replace_map);

$result = ['replace1', 'replace2', 'value3', 'value4'];

I can loop $origin and for each items lookup $replace_map by array_key_exists, and replace it with the value in $replace_map,

But I think this is not the best way, it sounds not efficient.

Is there better way to do this?

Further more, if the origin values are all integers, but some are negative, but the keys in map array are all positive,

like:

$origin = [-12345, 23456];
$map = [12345 => 98765];

also need change -12345 to -98765.

4 Answers 4

4

str_replace can handle arrays for search and replace parameters.

Try this code:

<?php
$origin = ['value1', 'value2', 'value3', 'value4'];
print_r($origin);
$search = ['value1', 'value2', 'value8'];
$replace = ['replace1', 'replace2', 'replace8'];
$result = str_replace($search, $replace, $origin);
print_r($result);

The output is

Array
(
    [0] => value1
    [1] => value2
    [2] => value3
    [3] => value4
)
Array
(
    [0] => replace1
    [1] => replace2
    [2] => value3
    [3] => value4
)

Also, str_replace handles as elements as strings, therefore, also integers will be replaced. Partial matches will also be replaced, for example:

echo str_replace(2, 5, -200);

will result in -500.

Sign up to request clarification or add additional context in comments.

1 Comment

Honestly didn't realise str_replace worked on subject arrays too
2
$origin = ['value1', 'value2', 'value3', '-2'];

$replace_map = [
    'value1' => 'replace1',
    'value2' => 'replace2',
    'value8' => 'replace8',
    2 => 77 
];

$new = array_map(function($i) use($replace_map) {
                   return preg_replace_callback('/^(-)*(.+)$/', 
                         function($m) use($replace_map) {
                            if(!isset($replace_map[$m[2]]))
                              return($m[0]);
                            return $m[1] . $replace_map[$m[2]];
                         },$i); 
                   }, $origin);
print_r($new);

result

Array
(
    [0] => replace1
    [1] => replace2
    [2] => value3
    [3] => -77
)

Comments

2

You can use array_map to run str_replace on each of the array values, like so:

$origin = ['value1', 'value2', 'value3', 'value4'];
$result = array_map('myReplace', $origin);
echo '<pre>' . print_r($result, true) . '</pre>';

function myReplace($value) {
    $replace_map = [
        'value1' => 'replace1',
        'value2' => 'replace2',
        'value8' => 'replace8',
    ];
    return str_replace(array_keys($replace_map), array_values($replace_map), $value);
}

Or for newer versions of PHP you can use an anonymous function

$replace_map = [
    'value1' => 'replace1',
    'value2' => 'replace2',
    'value8' => 'replace8',
];
$origin = ['value1', 'value2', 'value3', 'value4'];
$result = array_map(function($value) use ($replace_map) {
    return str_replace(array_keys($replace_map), array_values($replace_map), $value);
}, $origin);
echo '<pre>' . print_r($result, true) . '</pre>';

2 Comments

It's good to know str_replace can handle arrays, but will it replace values that are partly matched, like replace 12345 to 98745 if in map there is 123 => 987 ?
In that case it's best to use preg_replace matching the entire string
0

I think there is much room for improvement in @splash58's unexplained answer. preg_replace_callback() can receive array type data as its 3rd parameter so the array_map() wrapper is not necessary. The inner workings can be simplified too.

The other answers that are employing str_replace() cannot be trusted because they will make partial replacements. @Alexander admits this in his answer, but JamieBicknell admits it in a comment. @JamieBicknell's replaces multiple partial matches

Since the leading negative symbol should not be replaced, we make it an optional match that we do not replace.

Code: (Demo)

$origin = ['value1', 'value2', 'value3', '-2', '2', '22'];

$replace_map = [
    'value1' => 'replace1',
    'value2' => 'replace2',
    'value8' => 'replace8',
    2 => 77
];

var_export(
    preg_replace_callback(
        '~^-?\K.*$~',
        function($m) use($replace_map) {
            return $replace_map[$m[0]] ?? $m[0];
        },
        $origin
    )
);

If you are on PHP7.4 or higher, the syntax can be made more brief by using arrow function syntax.

var_export(
    preg_replace_callback('~^-?\K.*$~', fn($m)=> $replace_map[$m[0]] ?? $m[0], $origin)
);

Output (from both snippets):

array (
  0 => 'replace1',
  1 => 'replace2',
  2 => 'value3',
  3 => '-77',
  4 => '77',
  5 => '22',
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.