tags:

views:

198

answers:

4

Is it possible to do case-insensitive comparison when using the in_array function?

So with a source array like this:

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

The following lookups would all return true:

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

What function or set of functions would do the same? I don't think in_array itself can do this.

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

Source: php.net in_array manual page.

Gazler
If you know what is in the array, you can leave out the array_map; but this is a good example.
Don
Who downvoted a perfectly good example and solution?
Doug Neiner
I did actually. Because mapping the array on every call is, well, ludicrous.
cletus
Also, assuming (like Chacha) this comes direct from the docs, it's better to block quote it.
cletus
+2  A: 

The obvious thing to do is just convert the search term to lowercase:

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

of course if there are uppercase letters in the array you'll need to do this first:

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

and search that. There's no point in doing strtolower on the whole array with every search.

Searching arrays however is linear. If you have a large array or you're going to do this a lot, it would be better to put the search terms in key of the array as this will be much faster access:

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

then

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

The only issue here is that array keys must be unique so if you have a collision (eg "One" and "one") you will lose all but one.

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

From Documenation

Chacha102
You should blockquote code (or anything really) you get from somewhere else.
cletus
I figured that the 'From Documentation' with a link would be sufficient...
Chacha102
Just to be clear. It's not a criticism. Just a suggestion (and only my opinion, nothing official). :) At least if I copy a code snippet from a page I'll block quote it.
cletus
Plus, using a code block better describes it, as it is 'code'. Block quoting it does not allow for it to be properly formatted.
Chacha102
You can put a code block inside a block quote.
cletus
I stand corrected, after using the actual button to add `>` to every line, it works. I am just used to manually putting the `>` at the first line.
Chacha102
I'm used to using ctrl-Q to do it. That has one problem with code blocks because for some reason it wraps lines. Don't ask me why. But you can just either correct that or manually put a `>` at the start of each line.
cletus
Thanks for the tip on the formating. I still don't copy answers. :)
Chacha102
No you didn't. But that's the issue with not blockquoting. Otherwise it would be clearer (on both of your parts). It did look a little weird though that you'd both put the same code snippet and both put the same text in the same position with you putting link text being the only difference. Anyway +1 for the effort.
cletus
+4  A: 

you can use preg_grep()

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

print_r( preg_grep( "/ONe/i" , $a ) );
ghostdog74
+1 good suggestion
cletus
Definitely the most elegant solution.
Gazler