Función PHP in_array sensible a mayúsculas y minúsculas


131

¿Es posible hacer una comparación entre mayúsculas y minúsculas al usar la in_arrayfunción?

Entonces, con una matriz fuente como esta:

$a= array(
 'one',
 'two',
 'three',
 'four'
);

Las siguientes búsquedas volverían todas verdaderas:

in_array('one', $a);
in_array('two', $a);
in_array('ONE', $a);
in_array('fOUr', $a);

¿Qué función o conjunto de funciones haría lo mismo? No creo que in_arraypueda hacer esto.

Respuestas:


101

puedes usar preg_grep():

$a= array(
 'one',
 'two',
 'three',
 'four'
);

print_r( preg_grep( "/ONe/i" , $a ) );

37
el uso de expresiones regulares no es una buena solución, porque puede ser lento ... tal vez array_map es más rápido
— phil-opp

55
Para que sea un reemplazo directo para in_array, devolver un bool, se convierte en: count(preg_grep('/^'.preg_quote($needle).'/$',$a)>0). No tan elegante, entonces. (Observe que los caracteres ^ y $ son obligatorios, a menos que se desee una coincidencia parcial). Sin embargo, si realmente desea que se devuelvan las entradas coincidentes, me gusta esta solución.
— Darren Cook, el

2
El último comentario contiene un error de sintaxis: / $ debería ser $ / en su lugar.
— Gogowitsch

1
@DarrenCook, por lo que sé, un bool cast también funcionaría (bool) preg_grep ('/ ^'. Preg_quote ($ needle). '$ /', $ A), ya que una matriz vacía se convertiría en falso
— arraintxo

8
Parece que la forma más fácil de hacerlo es simplemente convertir a minúsculas.
— Joshua Dance

229

Lo obvio es simplemente convertir el término de búsqueda a minúsculas:

if (in_array(strtolower($word), $array)) { 
  ...

por supuesto, si hay letras mayúsculas en la matriz, primero deberá hacer esto:

$search_array = array_map('strtolower', $array);

y busca eso. No tiene sentido hacer strtolowertodo el conjunto con cada búsqueda.

Sin embargo, la búsqueda de matrices es lineal. Si tiene una matriz grande o va a hacer esto mucho, sería mejor poner los términos de búsqueda en la clave de la matriz, ya que este será un acceso mucho más rápido:

$search_array = array_combine(array_map('strtolower', $a), $a);

luego

if ($search_array[strtolower($word)]) { 
  ...

El único problema aquí es que las claves de matriz deben ser únicas, por lo que si tiene una colisión (por ejemplo, "Una" y "una") perderá todas menos una.


23
Esta debería ser la respuesta aceptada. Agregar expresiones regulares a veces solo genera 2 problemas.
— Joshua Dance

1
¿No sería array_flip aquí una solución aún más rápida, en lugar de array_combine? $ search_array = array_flip (array_map ('strtolower', $ a));
— jakub_jo

una línea: in_array (strtolower ($ word), array_map ('strtolower', $ array))
— Andrew

1
@ Akira Yamamoto: ¿qué pasa con la edición "corregir sintaxis" ? No se nos permite corregir el código aquí. Lo hice retroceder.
— Funk Forty Niner el


113
function in_arrayi($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack));
}

De la documentación


3
Debe bloquear el código de cotización (o cualquier cosa realmente) que obtenga de otro lugar.
— cletus

3
Para ser claro. No es una crítica. Solo una sugerencia (y solo mi opinión, nada oficial). :) Al menos si copio un fragmento de código de una página, bloquearé la cita.
— cletus

3
Además, usar un bloque de código lo describe mejor, ya que es 'código'. La cita en bloque no permite que se formatee correctamente.
— Tyler Carter

Estoy corregido, después de usar el botón real para agregar >a cada línea, funciona. Estoy acostumbrado a poner manualmente el >en la primera línea.
— Tyler Carter

Estoy acostumbrado a usar ctrl-Q para hacerlo. Eso tiene un problema con los bloques de código porque por alguna razón envuelve líneas. No me preguntes por qué. Pero puede corregir eso o poner manualmente un >al comienzo de cada línea.
— cletus

50
function in_arrayi($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack));
}

Fuente: página del manual php.net in_array.


Si sabe lo que hay en la matriz, puede omitir la matriz_mapa; Pero este es un buen ejemplo.
— Don

2
En realidad lo hice. Porque mapear la matriz en cada llamada es, bueno, ridículo.
— cletus

Además, suponiendo (como Chacha) que esto viene directamente de los documentos, es mejor bloquearlo entre comillas.
— cletus

10

Supongamos que quiere usar el in_array, así es cómo puede hacer que el caso de búsqueda no sea sensible.

Mayúsculas y minúsculas en_array ():

foreach($searchKey as $key => $subkey) {

     if (in_array(strtolower($subkey), array_map("strtolower", $subarray)))
     {
        echo "found";
     }

}

Mayúsculas y minúsculas normales:

foreach($searchKey as $key => $subkey) {

if (in_array("$subkey", $subarray))

     {
        echo "found";
     }

}

2

Lo anterior es correcto si suponemos que las matrices pueden contener solo cadenas, pero las matrices también pueden contener otras matrices. Además, la función in_array () puede aceptar una matriz para $ needle, por lo que strtolower ($ needle) no funcionará si $ needle es una matriz y array_map ('strtolower', $ haystack) no funcionará si $ haystack contiene otro matrices, pero dará como resultado "Advertencia de PHP: strtolower () espera que el parámetro 1 sea una cadena, matriz dada".

Ejemplo:

$needle = array('p', 'H');
$haystack = array(array('p', 'H'), 'U');

Así que creé una clase auxiliar con los métodos relevantes, para hacer comprobaciones in_array () sensibles a mayúsculas y minúsculas. También estoy usando mb_strtolower () en lugar de strtolower (), por lo que se pueden usar otras codificaciones. Aquí está el código:

class StringHelper {

public static function toLower($string, $encoding = 'UTF-8')
{
    return mb_strtolower($string, $encoding);
}

/**
 * Digs into all levels of an array and converts all string values to lowercase
 */
public static function arrayToLower($array)
{
    foreach ($array as &$value) {
        switch (true) {
            case is_string($value):
                $value = self::toLower($value);
                break;
            case is_array($value):
                $value = self::arrayToLower($value);
                break;
        }
    }
    return $array;
}

/**
 * Works like the built-in PHP in_array() function — Checks if a value exists in an array, but
 * gives the option to choose how the comparison is done - case-sensitive or case-insensitive
 */
public static function inArray($needle, $haystack, $case = 'case-sensitive', $strict = false)
{
    switch ($case) {
        default:
        case 'case-sensitive':
        case 'cs':
            return in_array($needle, $haystack, $strict);
            break;
        case 'case-insensitive':
        case 'ci':
            if (is_array($needle)) {
                return in_array(self::arrayToLower($needle), self::arrayToLower($haystack), $strict);
            } else {
                return in_array(self::toLower($needle), self::arrayToLower($haystack), $strict);
            }
            break;
    }
}
}

1

Escribí una función simple para verificar un valor insensible en una matriz, el código está debajo.

función:

function in_array_insensitive($needle, $haystack) {
   $needle = strtolower($needle);
   foreach($haystack as $k => $v) {
      $haystack[$k] = strtolower($v);
   }
   return in_array($needle, $haystack);
}

cómo utilizar:

$array = array('one', 'two', 'three', 'four');
var_dump(in_array_insensitive('fOUr', $array));

1
/**
 * in_array function variant that performs case-insensitive comparison when needle is a string.
 *
 * @param mixed $needle
 * @param array $haystack
 * @param bool $strict
 *
 * @return bool
 */
function in_arrayi($needle, array $haystack, bool $strict = false): bool
{

    if (is_string($needle)) {

        $needle = strtolower($needle);

        foreach ($haystack as $value) {

            if (is_string($value)) {
                if (strtolower($value) === $needle) {
                    return true;
                }
            }

        }

        return false;

    }

    return in_array($needle, $haystack, $strict);

}


/**
 * in_array function variant that performs case-insensitive comparison when needle is a string.
 * Multibyte version.
 *
 * @param mixed $needle
 * @param array $haystack
 * @param bool $strict
 * @param string|null $encoding
 *
 * @return bool
 */
function mb_in_arrayi($needle, array $haystack, bool $strict = false, ?string $encoding = null): bool
{

    if (null === $encoding) {
        $encoding = mb_internal_encoding();
    }

    if (is_string($needle)) {

        $needle = mb_strtolower($needle, $encoding);

        foreach ($haystack as $value) {

            if (is_string($value)) {
                if (mb_strtolower($value, $encoding) === $needle) {
                    return true;
                }
            }

        }

        return false;

    }

    return in_array($needle, $haystack, $strict);

}

Finalmente. Pasaron 8 años antes de que alguien interviniera y proporcionara la técnica más eficiente, una tempranareturn . Cuando solo se necesita encontrar 1 de la aguja, no tiene sentido seguir iterando después de encontrarla. Sin embargo, corregiría un error tipográfico, hornearía el concepto $ estricto y realizaría algunos ajustes , tal vez algo cercano a 3v4l.org/WCTi2 . Esta publicación no es perfecta, pero su corazón está en el lugar correcto.
— mickmackusa

0
$a = [1 => 'funny', 3 => 'meshgaat', 15 => 'obi', 2 => 'OMER'];  

$b = 'omer';

function checkArr($x,$array)
{
    $arr = array_values($array);
    $arrlength = count($arr);
    $z = strtolower($x);

    for ($i = 0; $i < $arrlength; $i++) {
        if ($z == strtolower($arr[$i])) {
            echo "yes";
        }  
    } 
};

checkArr($b, $a);

1
Por favor, agregue una descripción de la solución que está proponiendo.
— il_raffa

-2
  • in_array acepta estos parámetros: in_array (búsqueda, matriz, tipo)
  • si el parámetro de búsqueda es una cadena y el parámetro de tipo se establece en TRUE, la búsqueda distingue entre mayúsculas y minúsculas.
  • para que la búsqueda ignore el caso, sería suficiente usarlo así:

$ a = array ('uno', 'dos', 'tres', 'cuatro');

$ b = en_array ('UNO', $ a, falso);


66
El tercer parámetro controla si se verifica o no el tipo de variable, no el caso . Cuando truese utilizarán comparaciones de tipo estrictas, p '1' !== 1. Ej . Cuando falsese utilizará el tipo malabarismo, p '1' == 1. Ej . Consulte php.net/in_array y php.net/manual/en/types.comparisons.php para obtener documentación.
— leepowers
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.