PHP büyük / küçük harfe duyarsız in_array işlevi


131

Kullanırken büyük / küçük harfe duyarlı olmayan karşılaştırma yapmak mümkün mü in_arrayİşlevi ?

Yani bunun gibi bir kaynak dizisi ile:

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

Aşağıdaki aramaların tümü doğru döndürür:

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

Hangi işlev veya işlev kümesi aynı işlevi görür? Bunu in_arraykendisinin yapabileceğini sanmıyorum.

Yanıtlar:


101

kullanabilirsiniz preg_grep():

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

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

37
düzenli ifadeler kullanmak iyi bir çözüm değildir, çünkü yavaş olabilir ... belki array_map daha hızlıdır
phil-opp

5
Bu bir drop-in in_array için değiştirilmesi yapmak bir bool dönen için, o olur: count(preg_grep('/^'.preg_quote($needle).'/$',$a)>0). O kadar zarif değil. (Kısmi eşleştirme istenmedikçe ^ ve $ karakterlerinin gerekli olduğuna dikkat edin.) Ancak, eşleşen girdilerin döndürülmesini istiyorsanız, bu çözümü beğendim.
Darren Cook

2
Son yorum bir sözdizimi hatası içeriyor: / $ bunun yerine $ / olmalıdır.
Gogowitsch

1
@DarrenCook Bool cast'in de işe yarayacağını bildiğim kadarıyla (bool) preg_grep ('/ ^'. Preg_quote ($ iğne). '$ /', $ A), boş bir dizinin
yanlışa dönüşmesi

8
Görünüşe göre, gitmenin daha kolay yolu, sadece küçük harfe dönüştürmektir.
Joshua Dance

229

Yapılması gereken bariz şey, arama terimini küçük harfe dönüştürmektir:

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

tabii ki dizide büyük harfler varsa önce bunu yapmanız gerekir:

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

ve onu arayın. strtolowerHer aramada tüm dizi üzerinde yapmanın bir anlamı yok .

Dizilerin aranması ise doğrusaldır. Büyük bir diziniz varsa veya bunu çok yapacaksanız, arama terimlerini dizinin anahtarına koymak daha iyi olacaktır, çünkü bu çok daha hızlı erişim olacaktır:

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

sonra

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

Buradaki tek sorun, dizi anahtarlarının benzersiz olması gerektiğidir, bu nedenle bir çarpışmanız varsa (örneğin, "Bir" ve "bir"), biri dışında hepsini kaybedersiniz.


23
Kabul edilen cevap bu olmalıdır. Normal ifadeler eklemek bazen 2 problem yaratır.
Joshua Dance

1
Burada array_flip, array_combine yerine daha hızlı bir çözüm olmaz mıydı? $ arama_dizisi = array_flip (dizi_map ('strtolower', $ a));
jakub_jo

bir satır: in_array (strtolower ($ kelime), array_map ('strtolower', $ array))
Andrew

1
@Akira Yamamoto - "sözdizimini düzelt" düzenlemesinde ne var ? Burada kodu düzeltmemize izin verilmiyor. Geri aldım.
Funk Forty Niner


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

Gönderen Belgeler


3
Başka bir yerden aldığınız alıntı kodunu (veya gerçekten herhangi bir şeyi) engellemelisiniz.
cletus

3
Açık olmak gerekirse. Bu bir eleştiri değil. Sadece bir öneri (ve sadece benim fikrim, resmi değil). :) En azından bir sayfadan bir kod parçacığı kopyalarsam alıntı yapılmasını engellerim.
cletus

3
Ayrıca, bir kod bloğu kullanmak, onu 'kod' olduğu için daha iyi tanımlar. Alıntı yapmanın engellenmesi, düzgün biçimlendirilmesine izin vermez.
Tyler Carter

Düzeltilmiş duruyorum, >her satıra eklemek için gerçek düğmeyi kullandıktan sonra çalışıyor. Ben sadece >ilk satıra elle koymaya alışkınım .
Tyler Carter

Bunu yapmak için ctrl-Q kullanmaya alışkınım. Bunun kod bloklarıyla ilgili bir sorunu var çünkü bir nedenden dolayı satırları sarmalıyor. Bana neden diye sorma. Ancak bunu düzeltebilir veya >her satırın başına manuel olarak bir tane koyabilirsiniz .
cletus

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

Kaynak: php.net in_array kılavuz sayfası.


Dizide ne olduğunu biliyorsanız, array_map'i dışarıda bırakabilirsiniz; ama bu iyi bir örnek.
Don

2
Aslında yaptım. Çünkü her aramada diziyi eşleştirmek çok saçma.
cletus

Ayrıca (Chacha gibi) bunun doğrudan dokümanlardan geldiğini varsayarsak, alıntıyı engellemek daha iyidir.
cletus

10

Diyelim ki in_array'i kullanmak istiyorsunuz, işte arama durumunu nasıl duyarsız hale getirebilirsiniz.

Büyük / küçük harfe duyarsız in_array ():

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

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

}

Normal büyük / küçük harfe duyarlı:

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

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

     {
        echo "found";
     }

}

2

Dizilerin yalnızca dizeler içerebileceğini varsayarsak, yukarıdakiler doğrudur, ancak diziler başka dizileri de içerebilir. Ayrıca in_array () işlevi, $ iğne için bir dizi kabul edebilir, bu nedenle, $ iğne bir diziyse ve array_map ('strtolower', $ samanlık), $ samanlık başka bir şey içeriyorsa, strtolower ($ iğne) çalışmayacaktır. diziler, ancak "PHP uyarısı: strtolower () parametre 1'in dizge olmasını bekler, dizi verilir".

Misal:

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

Bu yüzden, büyük / küçük harfe duyarlı ve büyük / küçük harfe duyarlı in_array () kontrolleri yapmak için releveant yöntemlerle bir yardımcı sınıf oluşturdum. Ayrıca strtolower () yerine mb_strtolower () kullanıyorum, bu nedenle diğer kodlamalar kullanılabilir. İşte kod:

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

Aşağıdaki kodun olduğu bir dizide duyarsız bir değeri kontrol etmek için basit bir işlev yazdım.

fonksiyon:

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

nasıl kullanılır:

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

}

En sonunda. Birinin harekete geçmesi ve en verimli tekniği sağlaması 8 yıl sürdü - erkenreturn . İğneden yalnızca 1 tanesini bulmaya ihtiyaç duyduğunuzda, onu bulduktan sonra yinelemeye devam etmek anlamsızdır. Bir yazım hatasını düzeltir , $ sıkı konseptinde pişirir ve yine de bazı iyileştirmeler yaparım , belki de 3v4l.org/WCTi2'ye yakın bir şey . Bu gönderi mükemmel değil ama kalbi doğru yerde.
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
Lütfen önerdiğiniz çözümün bir tanımını ekleyin.
il_raffa

-2
  • in_array şu parametreleri kabul eder: in_array (arama, dizi, tür)
  • arama parametresi bir dizeyse ve tür parametresi TRUE olarak ayarlanmışsa, arama büyük / küçük harfe duyarlıdır.
  • bu nedenle, aramanın durumu yok sayması için, şu şekilde kullanılması yeterli olacaktır:

$ a = array ('bir', 'iki', 'üç', 'dört');

$ b = in_array ('BİR', $ a, yanlış);


6
Olsun veya olmasın Üçüncü parametre kontrolleri tipi değişkenin kontrol edilir, değil durum . Ne zaman truesıkı tip karşılaştırmalar kullanılacaktır, örneğin '1' !== 1. Ne zaman falsetipi hokkabazlık kullanılacaktır, örneğin '1' == 1. Belgeler için php.net/in_array ve php.net/manual/en/types.comparisons.php bakın .
leepowers
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.