Hàm in_array không phân biệt chữ hoa chữ thường


131

Có thể làm so sánh không phân biệt chữ hoa chữ thường khi sử dụng in_arrayhàm không?

Vì vậy, với một mảng nguồn như thế này:

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

Các tra cứu sau đây sẽ trả về đúng sự thật:

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

Hàm hoặc tập hợp hàm nào sẽ làm giống nhau? Tôi không nghĩ rằng in_arraychính nó có thể làm điều này.

Câu trả lời:


101

bạn có thể sử dụng preg_grep():

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

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

37
sử dụng các biểu thức chính quy không phải là một giải pháp tốt, bởi vì nó có thể chậm ... có thể mảng_map nhanh hơn
phil-opp

5
Để biến nó thành một thay thế thả vào cho in_array, trả về một bool, nó trở thành : count(preg_grep('/^'.preg_quote($needle).'/$',$a)>0). Không thanh lịch, vậy thì. (Lưu ý các ký tự ^ và $ là bắt buộc, trừ khi mong muốn khớp một phần.) Tuy nhiên nếu bạn thực sự muốn các mục phù hợp được trả về, tôi thích giải pháp này.
Darren Cook

2
Nhận xét cuối cùng chứa lỗi cú pháp: / $ nên là $ / thay vào đó.
Gogowitsch

1
@DarrenCook theo như tôi biết, một bool cast cũng sẽ hoạt động (bool) preg_grep ('/ ^'. Preg_quote ($ kim). '$ /', $ A), vì một mảng trống sẽ chuyển thành false
arraintxo

8
Có vẻ như cách dễ dàng hơn là chỉ chuyển đổi thành chữ thường.
Vũ điệu Joshua

229

Điều rõ ràng cần làm là chỉ cần chuyển đổi cụm từ tìm kiếm thành chữ thường:

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

tất nhiên nếu có các chữ cái in hoa trong mảng bạn sẽ cần phải làm điều này trước tiên:

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

và tìm kiếm nó. Không có điểm nào trong việc thực hiện strtolowertrên toàn bộ mảng với mọi tìm kiếm.

Tìm kiếm mảng tuy nhiên là tuyến tính. Nếu bạn có một mảng lớn hoặc bạn sẽ làm điều này rất nhiều, tốt hơn là đặt các cụm từ tìm kiếm vào khóa của mảng vì điều này sẽ truy cập nhanh hơn nhiều :

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

sau đó

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

Vấn đề duy nhất ở đây là các khóa mảng phải là duy nhất nên nếu bạn có xung đột (ví dụ: "Một" và "một"), bạn sẽ mất tất cả trừ một.


23
Đây phải là câu trả lời được chấp nhận. Thêm biểu thức thông thường đôi khi chỉ làm cho 2 vấn đề.
Vũ điệu Joshua

1
Sẽ không Array_flip ở đây là một giải pháp thậm chí nhanh hơn, thay vì mảng_combine? $ search_array = mảng_flip (mảng_map ('strtolower', $ a));
jakub_jo

một dòng: in_array (strtolower ($ word), Array_map ('strtolower', $ mảng))
Andrew

1
@Akira Yamamoto - chỉnh sửa "cú pháp sửa lỗi" là gì? Chúng tôi không được phép sửa mã ở đây. Tôi lăn nó trở lại.
Funk Bốn mươi Niner

Hoặc sử dụng mảng_change_key_case () safe.php.net/manual/en/feft.array-change-key-case.php
boctulus

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

Từ Tài liệu


3
Bạn nên mã blockquote (hoặc bất cứ thứ gì thực sự) bạn nhận được từ một nơi khác.
cletus

3
Chỉ để được rõ ràng. Đó không phải là một lời chỉ trích. Chỉ là một đề nghị (và chỉ ý kiến ​​của tôi, không có gì chính thức). :) Ít nhất nếu tôi sao chép một đoạn mã từ một trang, tôi sẽ chặn trích dẫn nó.
cletus

3
Thêm vào đó, sử dụng một khối mã mô tả tốt hơn về nó, vì đó là 'mã'. Chặn trích dẫn nó không cho phép nó được định dạng chính xác.
Tyler Carter

Tôi đứng chính xác, sau khi sử dụng nút thực tế để thêm >vào mỗi dòng, nó hoạt động. Tôi chỉ quen với việc đặt thủ công >ở dòng đầu tiên.
Tyler Carter

Tôi đã quen với việc sử dụng ctrl-Q để làm điều đó. Điều đó có một vấn đề với các khối mã bởi vì một số lý do, nó kết thúc các dòng. Đừng hỏi tôi tại sao. Nhưng bạn có thể sửa hoặc đặt thủ công >ở đầu mỗi dòng.
cletus

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

Nguồn: trang hướng dẫn sử dụng php.net in_array.


Nếu bạn biết những gì trong mảng, bạn có thể bỏ qua mảng_map; nhưng đây là một ví dụ tốt
Don

2
Tôi đã thực sự làm. Bởi vì ánh xạ mảng trên mỗi cuộc gọi là, tốt, lố bịch.
cletus

Ngoài ra, giả sử (như Chacha) điều này xuất phát trực tiếp từ các tài liệu, tốt hơn hết là chặn trích dẫn nó.
cletus

10

Giả sử bạn muốn sử dụng in_array, đây là cách bạn có thể làm cho trường hợp tìm kiếm không nhạy cảm.

Trường hợp không nhạy cảm in_array ():

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

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

}

Trường hợp bình thường nhạy cảm:

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

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

     {
        echo "found";
     }

}

2

Trên đây là chính xác nếu chúng ta giả sử rằng các mảng chỉ có thể chứa các chuỗi, nhưng các mảng cũng có thể chứa các mảng khác. Ngoài ra, hàm in_array () có thể chấp nhận một mảng cho $ kim, vì vậy strtolower ($ kim) sẽ không hoạt động nếu $ kim là một mảng và mảng_map ('strtolower', $ haystack) sẽ không hoạt động nếu $ haystack chứa khác mảng, nhưng sẽ dẫn đến "cảnh báo PHP: strtolower () mong muốn tham số 1 là chuỗi, mảng đã cho".

Thí dụ:

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

Vì vậy, tôi đã tạo ra một lớp trợ giúp với các phương thức liên quan, để thực hiện kiểm tra in_array () không phân biệt chữ hoa chữ thường và chữ hoa chữ thường. Tôi cũng đang sử dụng mb_strtolower () thay vì strtolower (), vì vậy các bảng mã khác có thể được sử dụng. Đây là mã:

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

Tôi đã viết một hàm đơn giản để kiểm tra giá trị không nhạy cảm trong một mảng mã bên dưới.

chức năng:

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

cách sử dụng:

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

}

Cuối cùng. Phải mất 8 năm trước khi ai đó bước lên và cung cấp kỹ thuật hiệu quả nhất - sớmreturn . Khi chỉ cần tìm 1 kim, việc tiếp tục lặp lại sau khi tìm thấy nó là vô nghĩa. Tôi sẽ sửa một lỗi đánh máy, nướng trong khái niệm $ nghiêm ngặt và thực hiện một số tinh chỉnh, có lẽ là một cái gì đó gần với 3v4l.org/WCTi2 . Bài đăng này không hoàn hảo, nhưng trái tim của nó ở đúng nơi.
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
Xin vui lòng, thêm một mô tả của giải pháp bạn đang đề xuất.
il_raffa

-2
  • in_array chấp nhận các tham số này: in_array (tìm kiếm, mảng, loại)
  • nếu tham số tìm kiếm là một chuỗi và tham số loại được đặt thành TRUE, thì tìm kiếm có phân biệt chữ hoa chữ thường.
  • Vì vậy, để làm cho tìm kiếm bỏ qua trường hợp, nó sẽ là đủ để sử dụng nó như thế này:

$ a = mảng ('một', 'hai', 'ba', 'bốn');

$ b = in_array ('MỘT', $ a, sai);


6
Tham số thứ ba kiểm soát xem loại biến có được kiểm tra hay không, không phải là trường hợp . Khi trueso sánh loại nghiêm ngặt sẽ được sử dụng, ví dụ '1' !== 1. Khi falseloại tung hứng sẽ được sử dụng, ví dụ '1' == 1. Xem php.net/in_arrayphp.net/manual/en/types.comparisons.php để biết tài liệu.
leepowers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.