PHP-Funktion ohne Berücksichtigung der Groß- und Kleinschreibung in_array

131

Ist es möglich, bei Verwendung der in_arrayFunktion einen Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung durchzuführen ?

Also mit einem Quell-Array wie diesem:

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

Die folgenden Suchvorgänge würden alle true zurückgeben:

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

Welche Funktion oder Funktionsgruppe würde dasselbe tun? Ich glaube nicht, dass er das in_arraykann.

Leepowers
quelle

Antworten:

101

Sie können verwenden preg_grep():

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

print_r( preg_grep( "/ONe/i" , $a ) );
Ghostdog74
quelle
37
Die Verwendung regulärer Ausdrücke ist keine gute Lösung, da sie langsam sein kann. Vielleicht ist array_map schneller
phil-opp
5
Um es zu einem Drop-In-Ersatz für in_array zu machen und einen Bool zurückzugeben, wird es zu : count(preg_grep('/^'.preg_quote($needle).'/$',$a)>0). Also nicht so elegant. (Beachten Sie, dass die Zeichen ^ und $ erforderlich sind, es sei denn, eine teilweise Übereinstimmung ist erwünscht.) Wenn Sie jedoch tatsächlich möchten, dass die übereinstimmenden Einträge zurückgegeben werden, gefällt mir diese Lösung.
Darren Cook
2
Der letzte Kommentar enthält einen Syntaxfehler: / $ sollte stattdessen $ / sein.
Gogowitsch
1
@DarrenCook soweit ich weiß, würde eine Bool-Besetzung auch funktionieren (bool) preg_grep ('/ ^'. Preg_quote ($ Nadel). '$ /', $ A), da ein leeres Array auf false umgewandelt würde
arraintxo
8
Der einfachere Weg scheint darin zu bestehen, nur in Kleinbuchstaben umzuwandeln.
Joshua Dance
229

Es liegt auf der Hand, den Suchbegriff in Kleinbuchstaben umzuwandeln:

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

Wenn das Array Großbuchstaben enthält, müssen Sie dies natürlich zuerst tun:

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

und suche das. Es macht keinen Sinn, strtolowerbei jeder Suche das gesamte Array zu bearbeiten.

Das Durchsuchen von Arrays ist jedoch linear. Wenn Sie ein großes Array haben oder dies häufig tun, ist es besser, die Suchbegriffe in den Schlüssel des Arrays einzugeben, da dies einen viel schnelleren Zugriff ermöglicht:

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

dann

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

Das einzige Problem hierbei ist, dass Array-Schlüssel eindeutig sein müssen. Wenn Sie also eine Kollision haben (z. B. "Eins" und "Eins"), verlieren Sie alle bis auf einen.

Cletus
quelle
23
Dies sollte die akzeptierte Antwort sein. Das Hinzufügen von regulären Ausdrücken verursacht manchmal nur zwei Probleme.
Joshua Dance
1
Wäre array_flip hier nicht eine noch schnellere Lösung als array_combine? $ search_array = array_flip (array_map ('strtolower', $ a));
jakub_jo
eine Zeile: in_array (strtolower ($ word), array_map ('strtolower', $ array))
Andrew
1
@Akira Yamamoto - Was ist mit der "Fix Syntax" bearbeiten ? Wir dürfen hier keinen Code reparieren. Ich rollte es zurück.
Funk Forty Niner
Oder verwenden Sie array_change_key_case () secure.php.net/manual/en/function.array-change-key-case.php
boctulus
113
function in_arrayi($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack));
}

Aus der Dokumentation

Tyler Carter
quelle
3
Sie sollten Blockquote-Code (oder irgendetwas wirklich) blockieren, den Sie von einem anderen Ort erhalten.
Cletus
3
Nur um das klar zu stellen. Es ist keine Kritik. Nur ein Vorschlag (und nur meine Meinung, nichts offizielles). :) Zumindest wenn ich ein Code-Snippet von einer Seite kopiere, blockiere ich das Zitat.
Cletus
3
Die Verwendung eines Codeblocks beschreibt ihn außerdem besser, da es sich um "Code" handelt. Durch Blockzitate kann es nicht richtig formatiert werden.
Tyler Carter
Ich stehe korrigiert da, nachdem ich die eigentliche Schaltfläche zum Hinzufügen >zu jeder Zeile verwendet habe, funktioniert es. Ich bin es einfach gewohnt, das manuell >in die erste Zeile zu setzen.
Tyler Carter
Ich bin es gewohnt, dafür Strg-Q zu verwenden. Das hat ein Problem mit Codeblöcken, weil es aus irgendeinem Grund Zeilen umschließt. Frag mich nicht warum. Sie können dies jedoch entweder korrigieren oder manuell ein >am Anfang jeder Zeile einfügen.
Cletus
50
function in_arrayi($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack));
}

Quelle: php.net in_array Handbuchseite.

Gazler
quelle
Wenn Sie wissen, was sich im Array befindet, können Sie die array_map weglassen. aber das ist ein gutes Beispiel.
Don
2
Ich habe es tatsächlich getan. Weil das Zuordnen des Arrays bei jedem Aufruf lächerlich ist.
Cletus
Unter der Annahme, dass dies (wie Chacha) direkt aus den Dokumenten stammt, ist es auch besser, das Zitat zu blockieren.
Cletus
10

Angenommen, Sie möchten das in_array verwenden. Hier erfahren Sie, wie Sie die Groß- und Kleinschreibung nicht berücksichtigen können.

Groß- und Kleinschreibung nicht berücksichtigen in_array ():

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

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

}

Normale Groß- und Kleinschreibung beachten:

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

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

     {
        echo "found";
     }

}
Mike Q.
quelle
2

Das Obige ist richtig, wenn wir annehmen, dass Arrays nur Strings enthalten können, Arrays aber auch andere Arrays. Die Funktion in_array () kann auch ein Array für $ Needle akzeptieren, sodass Strtolower ($ Needle) nicht funktioniert, wenn $ Needle ein Array ist und Array_Map ('Strtolower', $ Haystack) nicht funktioniert, wenn $ Haystack andere enthält Arrays, führt jedoch zu "PHP-Warnung: strtolower () erwartet, dass Parameter 1 Zeichenfolge ist, Array angegeben".

Beispiel:

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

Also habe ich eine Hilfsklasse mit den relevanten Methoden erstellt, um in_array () zwischen Groß- und Kleinschreibung zu unterscheiden und zwischen Groß- und Kleinschreibung zu unterscheiden. Ich verwende auch mb_strtolower () anstelle von strtolower (), damit andere Codierungen verwendet werden können. Hier ist der Code:

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;
    }
}
}
Alex
quelle
1

Ich habe eine einfache Funktion geschrieben, um in einem Array, in dem sich der Code befindet, nach einem unempfindlichen Wert zu suchen.

Funktion:

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

wie benutzt man:

$array = array('one', 'two', 'three', 'four');
var_dump(in_array_insensitive('fOUr', $array));
Jake
quelle
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);

}
Carlos Coelho
quelle
Schließlich. Es dauerte 8 Jahre, bis jemand auftauchte und die effizienteste Technik bereitstellte - eine frühereturn . Wenn nur 1 Nadel gefunden werden muss, ist es sinnlos, nach dem Auffinden weiter zu iterieren. Ich würde einen Tippfehler beheben, das $ strict-Konzept einbrennen und einige Verbesserungen vornehmen, vielleicht etwas in der Nähe von 3v4l.org/WCTi2 . Dieser Beitrag ist nicht perfekt, aber sein Herz ist am richtigen Ort.
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);
omer
quelle
1
Bitte fügen Sie eine Beschreibung der von Ihnen vorgeschlagenen Lösung hinzu.
il_raffa
-2
  • in_array akzeptiert folgende Parameter: in_array (Suche, Array, Typ)
  • Wenn der Suchparameter eine Zeichenfolge ist und der Typparameter auf TRUE gesetzt ist, wird bei der Suche zwischen Groß- und Kleinschreibung unterschieden.
  • Damit die Suche den Fall ignoriert, reicht es aus, ihn wie folgt zu verwenden:

$ a = Array ('eins', 'zwei', 'drei', 'vier');

$ b = in_array ('ONE', $ a, false);

user1077915
quelle
6
Der dritte Parameter steuert , ob oder nicht der Typ der Variable überprüft wird, nicht der Fall . Wenn truestrenge Typvergleiche verwendet werden, z '1' !== 1. Wenn falseTyp Jonglieren verwendet wird, z '1' == 1. Dokumentation finden Sie unter php.net/in_array und php.net/manual/en/types.comparisons.php .
Leepowers