2011-12-29 77 views
18

que estaba buscando alguna función estándar de PHP para reemplazar algún valor de una matriz con otra, pero, sorprendentemente, no he encontrado ninguna, así que tengo que escribir mi propia:buscar y reemplazar el valor de matriz PHP

function array_replace_value(&$ar, $value, $replacement) 
{ 
    if (($key = array_search($ar, $value)) !== FALSE) { 
     $ar[$key] = $replacement; 
    } 
} 

Pero todavía me pregunto - por algo tan fácil que ya debe haber alguna función para ello! ¿O quizás una solución mucho más fácil que esta inventada por mí?

Tenga en cuenta que esta función solo hará un reemplazo. Estoy buscando soluciones existentes que de manera similar reemplacen una sola ocurrencia, así como aquellas que reemplazan todas las ocurrencias.

+0

Tenga en cuenta que las matrices se pasan por valor. Necesitarás devolver la nueva matriz de la función (haciendo coincidir el comportamiento del resto de las funciones 'array_ *') o hacer que 'array_replace_value' tome' $ ar' por referencia. – outis

+0

[str_replace] (http://www.php.net/str_replace)() toma arrays, pero no puede limitarlo a un reemplazo. – goat

+0

Gracias @outis, me di cuenta de esto durante la depuración mientras tanto :) – TMS

Respuesta

15

Si bien no es una función equivalente al código de ejemplo, se puede utilizar array_keys (con el parámetro de valor de búsqueda opcional), array_fill y array_replace para lograr la misma cosa:

EDITAR por Tomas: la el código no funcionaba, lo corrigió:

$ar = array_replace($ar, 
    array_fill_keys(
     array_keys($ar, $value), 
     $replacement 
    ) 
); 
+0

¿No 'array_replace()' supone que ya conoce las claves? El OP busca buscar y reemplazar por valor. –

+0

'array_replace' reemplaza por clave, no por valor. – outis

+0

así que primero podría encontrar la llave y luego reemplazarla. –

5

Pruebe esta función.

public function recursive_array_replace ($find, $replace, $array) { 
    if (!is_array($array)) { 
     return str_replace($find, $replace, $array); 
    } 

    $newArray = []; 
    foreach ($array as $key => $value) { 
     $newArray[$key] = recursive_array_replace($find, $replace, $value); 
    } 
    return $newArray; 
} 

¡Salud!

+0

Solo tome esto como una adición a su función. Esto procesa matrices multidimensionales. –

-1
<b>$green_key = array_search('green', $input); // returns the first key whose value is 'green' 

$ input [$ green_key] = 'apple'; // reemplazar 'verde' con 'manzana'

+0

Esto es básicamente lo que tiene Tomas, pero esto no soluciona el caso en el que un valor no está presente en la matriz. – outis

18

En lugar de una función que sólo reemplaza las ocurrencias de un valor en una matriz, está el más general array_map:

array_map(function ($v) use ($value, $replacement) { 
    return $v == $value ? $replacement : $v; 
}, $arr); 

Para reemplazar múltiples ocurrencias de múltiples valores utilizando array de valores => sustitución:

array_map(function ($v) use ($replacement) { 
    return isset($replacement[$v]) ? $replacement[$v] : $v; 
}, $arr); 

Para reemplazar una sola aparición de un valor, que tendría que utilizar array_search como lo hace. Debido a que la implementación es tan corta, no hay muchas razones para que los desarrolladores de PHP creen una función estándar para realizar la tarea. No quiere decir que no tiene sentido que cree una función de este tipo, si lo necesita con frecuencia.

+0

+1. gracias por la buena respuesta, no sabía esta sintaxis, sin embargo, usar el mapa y el código personalizado es una herramienta poderosa para esto, ¿podría ser ineficiente? Prefiero una solución "codificada" como la de Raghav. – TMS

+0

@Tomas: es la sintaxis a la que se refiere [funciones anónimas] (http://www.php.net/manual/en/functions.anonymous.php) y cierres? Exceptuando el adicional del especificador de "uso", eso es más semántico que la sintaxis. En cuanto a la eficiencia, si hay un impacto, es insignificante (a menos que esté realizando reemplazos en tal vez miles de matrices con cada solicitud). Un factor que afecta el rendimiento es que cada llamada a una función 'array_ *' creará una matriz adicional como resultado: una aquí, tres en Raghav.Como siempre, la creación de perfiles es la mejor forma de determinar el rendimiento. – outis

+0

... Tenga en cuenta que Raghav's no tiene nada codificado que esto no ocurra, ya que todos tienen los mismos valores paramaterizados (la matriz, el valor a reemplazar y el valor de reposición). Cualquier cosa difícil de codificar rara vez ofrece un beneficio notable en el rendimiento, ya que el costo de búsqueda variable es pequeño. – outis

3

Si el rendimiento es un problema, uno puede considerar no crear varias funciones dentro de array_map(). Tenga en cuenta que isset() es extremadamente rápido, y esta solución no llama a ninguna otra función.

$replacements = array(
    'search1' => 'replace1', 
    'search2' => 'replace2', 
    'search3' => 'replace3' 
); 
foreach ($a as $key => $value) { 
    if (isset($replacements[$value])) { 
     $a[$key] = $replacements[$value]; 
    } 
} 
0

Basado en respuesta Deept Raghav 's, he creado la solución de seguimiento que hace la búsqueda de expresiones regulares.

$arr = [ 
    'Array Element 1', 
    'Array Element 2', 
    'Replace Me', 
    'Array Element 4', 
]; 

$arr = array_replace(
    $arr, 
    array_fill_keys(
     array_keys(
      preg_grep('/^Replace/', $arr) 
     ), 
     'Array Element 3' 
    ) 
); 

echo '<pre>', var_export($arr), '</pre>'; 

PhpFiddle: http://phpfiddle.org/lite/code/un7u-j1pt

0

Dependiendo ya sea el valor, la tecla o ambos desea buscar y reemplazar en que podría hacer algo como esto:

$array = json_decode(str_replace($replace, $with, json_encode($array)), true); 

No estoy diciendo este es el más eficiente o elegante, pero agradable y simple.

1

¿Qué pasa con array_walk() con devolución de llamada?

$array = ['*pasta', 'cola', 'pizza']; 
$search = '*'; 
$replace = '\*'; 
array_walk($array, 
    function (&$v) use ($search, $replace){ 
     $v = str_replace($search, $replace, $v);  
    }                  
); 
print_r($array);