PHPの大文字と小文字を区別しないin_array関数


131

in_array関数を使用するときに大文字と小文字を区別しない比較を行うことは可能ですか?

したがって、次のようなソース配列を使用します。

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

次のルックアップはすべてtrueを返します。

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

どの機能または機能のセットが同じことを行いますか?私はin_arrayそれ自体はこれを行うことができないと思います。

回答:


101

あなたが使うことができますpreg_grep()

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

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

37
正規表現を使用することは、低速になる可能性があるため、良い解決策ではありません...おそらくarray_mapの方が高速です
phil-opp

5
これをin_arrayのドロップイン置換にして、ブール値を返すようにするには、次のようにします count(preg_grep('/^'.preg_quote($needle).'/$',$a)>0)。それほどエレガントではありません。(部分一致が必要でない限り、^と$の文字が必要であることに注意してください。)ただし、一致するエントリを実際に返したい場合は、このソリューションが気に入っています。
ダレン・クック

2
最後のコメントには構文エラーが含まれています。代わりに/ $は$ /である必要があります。
Gogowitsch

1
@DarrenCook私の知る限りでは、空の配列としても仕事(ブール値)preg_grep( '/ ^' preg_quote($針) '$ /'、$ aが。。)、falseにキャストしまうでしょうブールキャストを知っているように
arraintxo

8
小文字に変換する方が簡単な方法のようです。
ジョシュアダンス

229

明白なことは、検索語を小文字に変換することです。

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

もちろん、配列に大文字がある場合は、最初にこれを行う必要があります。

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

そしてそれを検索します。strtolowerすべての検索で配列全体を実行する意味はありません。

ただし、配列の検索は線形です。大規模な配列がある場合、またはこれを頻繁に実行する場合は、検索語を配列のキーに配置する方がアクセスが高速になるため、次のようにします。

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

その後

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

ここでの唯一の問題は、配列キーが一意でなければならないことです。そのため、衝突(たとえば、「1つ」と「1つ」)があると、1つを除くすべてが失われます。


23
これは受け入れられる答えになるはずです。正規表現を追加すると、2つの問題が発生する場合があります。
ジョシュアダンス

1
ここでarray_flipは、array_combineの代わりに、さらに高速な解決策ではないでしょうか?$ search_array = array_flip(array_map( 'strtolower'、$ a));
jakub_jo

1行:in_array(strtolower($ word)、array_map( 'strtolower'、$ array))
Andrew

1
@Akira Yamamoto- 「修正構文」編集とは何ですか?ここでコードを修正することはできません。元に戻しました。
Funk Forty Niner、

または、array_change_key_case()を使用します。secure.php.net/ manual
en /

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

ドキュメントから


3
他の場所から取得したコード(または実際には何でも)をブロック引用する必要があります。
cletus

3
ただ明確にします。それは批判ではありません。ただの提案です(そして私の意見だけで、公式のものはありません)。:)少なくとも、ページからコードスニペットをコピーする場合は、引用をブロックします。
cletus

3
さらに、コードブロックを使用すると、それが「コード」であるため、より適切に説明されます。ブロック引用すると、適切にフォーマットできません。
タイラーカーター

実際にボタンを使用し>てすべての行に追加した後、私は修正された状態で機能します。私は手動で>最初の行に置くことに慣れています。
タイラーカーター

私はそれをするためにctrl-Qを使用することに慣れています。何らかの理由で行を折り返すため、コードブロックには1つの問題があります。理由を聞かないでください。しかし、それを修正するか>、各行の先頭に手動でを置くことができます。
cletus

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

ソース:php.net in_arrayマニュアルページ。


配列の内容がわかっている場合は、array_mapを省略できます。しかし、これは良い例です。
ドン

2
実際にやった。なぜなら、すべての呼び出しで配列をマッピングするのは、とんでもないことだからです。
cletus

また、(Chachaのように)これがドキュメントから直接来ていると仮定すると、それをブロック引用するのが良いでしょう。
cletus

10

in_arrayを使用するとします。ここでは、検索で大文字と小文字を区別しないようにする方法を示します。

大文字と小文字を区別しないin_array():

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

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

}

通常の大文字と小文字を区別:

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

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

     {
        echo "found";
     }

}

2

配列に文字列のみを含めることができると仮定すると、上記は正しいですが、配列には他の配列も含めることができます。また、in_array()関数は$ needleの配列を受け入れることができるため、$ needleが配列の場合はstrtolower($ needle)は機能せず、$ haystackに他の配列が含まれている場合はarray_map( 'strtolower'、$ haystack)は機能しません配列ですが、「PHP警告:strtolower()はパラメータ1が文字列であり、配列が指定されていると想定しています」という結果になります。

例:

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

そのため、大文字と小文字を区別するin_array()チェックを行うために、関連するメソッドを含むヘルパークラスを作成しました。strtolower()の代わりにmb_strtolower()も使用しているため、他のエンコーディングを使用できます。これがコードです:

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

私は、コードが以下にある配列の無意味な値をチェックする簡単な関数を書きました。

関数:

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

使い方:

$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);

}

最後に。誰かがステップアップして最も効率的なテクニックを提供するまでに8年かかりました- 初期return。針の1つを見つける必要があるだけの場合、それを見つけた後も反復を続けても意味がありません。タイプミスを修正し、$ strictコンセプトを焼き、いくつかの改良を加えますが、おそらく3v4l.org/WCTi2に近いものでしょう。この投稿は完璧ではありませんが、その心は正しい場所にあります。
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
提案しているソリューションの説明を追加してください。
il_raffa

-2
  • in_arrayはこれらのパラメーターを受け入れます:in_array(search、array、type)
  • 検索パラメーターが文字列で、typeパラメーターがTRUEに設定されている場合、検索では大文字と小文字が区別されます。
  • したがって、検索で大文字と小文字を区別しないようにするには、次のように使用するだけで十分です。

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

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


6
3番目のパラメーターは、ケースではなく、変数のタイプをチェックするかどうかを制御します。場合は、厳密な型の比較は例えば、使用されます。タイプジャグリングを使用する場合。ドキュメントについては、php.net / in_arrayおよびphp.net/manual/en/types.comparisons.phpを参照してください。true'1' !== 1false'1' == 1
leepowers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.