3

I have a string

8,7,13,14,16

Whats the easiest way to determine if a given number is present in that string?

$numberA = "13";
$string = "8,7,13,14,16";

if($string magic $numberA){
$result = "Yeah, that number is in there";
} else {
$result = "Sorry.";
}

Looking for magic.

markus
  • 40,136
  • 23
  • 97
  • 142
mrpatg
  • 10,001
  • 42
  • 110
  • 169

5 Answers5

23
<?php 
in_array('13', explode(',', '8,7,13,14,16'));
?>

…will return whether '13' is in the string.

Just to elaborate: explode turns the string into an array, splitting it at each ',' in this case. Then, in_array checks if the string '13' is in the resulting array somewhere.

markus
  • 40,136
  • 23
  • 97
  • 142
slikts
  • 8,020
  • 1
  • 27
  • 47
  • Just to elaborate: `explode` turns the string into an array, splitting it at each ',' in this case. Then, `in_array` checks if the string '13' is in the resulting array somewhere. – gnud Oct 12 '09 at 09:05
  • this works too well aparently, returns true if the subject is 13, and the target contains a 1 or a 3, not just the whole subject itself. – mrpatg Oct 12 '09 at 09:18
  • 4
    No, patrick, it won't. exploding the sample string like in this answer, generates the array `array('8','7','13','14','16')`. – gnud Oct 12 '09 at 09:19
4

Another way, that might be more efficient for laaaaaaaarge strings, is using a regexp:

$numberA = "13";
$string = "8,7,13,14,16";

if(preg_match('/(^|,)'.$numberA.'($|,)/', $string)){
    $result = "Yeah, that number is in there";
} else {
    $result = "Sorry.";
}
gnud
  • 77,584
  • 5
  • 64
  • 78
  • That will also match `1,2,113`. – Gumbo Oct 12 '09 at 09:13
  • vava's way is probably a bit faster. If you're familiar with regexes, mine might be more self-explanatory, since it describes what we accept, instead of changing the input. – gnud Oct 12 '09 at 09:21
3
if (strpos(','.$string.',' , ','.$numberA.',') !== FALSE) {
    //found
}

Notice guard ',' chars, they will help to deal with '13' magic '1, 2, 133' case.

gnud
  • 77,584
  • 5
  • 64
  • 78
vava
  • 24,851
  • 11
  • 64
  • 79
  • 1
    But what about at the end, where it doesn't have a comma behind the number? – random Oct 12 '09 at 09:09
  • That's why I also added comma to the haystack string :) – vava Oct 12 '09 at 09:13
  • Nice. Somehow it never occured to me to concat a comma to the original string. I used a regex instead :F – gnud Oct 12 '09 at 09:13
  • As you said yourself: “13 is a part of 113” and `13,` is part of `113,`. – Gumbo Oct 12 '09 at 09:14
  • 1
    Like my first submission, this will fail if the last number is 113. Concat a comma at the start of each string to fix =) – gnud Oct 12 '09 at 09:16
1

Make sure you match the full number in the string, not just part of it.

function numberInList($num, $list) {
    return preg_match("/\b$num\b/", $list);
}
$string = "8,7,13,14,16";    
numberInList(13, $string); # returns 1
numberInList(8, $string); # returns 1
numberInList(1, $string); # returns 0
numberInList(3, $string); # returns 0
outis
  • 75,655
  • 22
  • 151
  • 221
-1

A simple string search should do if you are just checking to find existence of the string. I dont speak php but i think this is how it could be done.

$mystring = '8,7,13,14,16';
$findme   = '13';

if (preg_match('/(?>(^|[^0-9])'.$findme.'([^0-9]|$))/', $mystring)) {
    $result = "Yeah, that number is in there";
} else {
    $result = "Sorry.";
}
Jaskirat
  • 1,114
  • 1
  • 8
  • 17
  • 2
    simple search is not enough. 13 is a part of 113 :) – vava Oct 12 '09 at 09:07
  • 1
    See vava's answer for the proper way =) – gnud Oct 12 '09 at 09:12
  • Oh yeah i dint think of that. Hmm Then i guess the explode technique answer or maybe using regex would be a faster way – Jaskirat Oct 12 '09 at 09:13
  • @Jass, both probably slower, but explode looks better and more maintainable. Regexp is generally slow and explode will create and iterate over array. Also, guards can be pre-added, making it even faster :) – vava Oct 12 '09 at 09:17
  • On the other hand, original string can be pre-converted to associative array, this is the fastest way possible. – vava Oct 12 '09 at 09:18
  • Something like /(?>[^0-9]$the-number-to-be-found[^0-9])/ could be fast enough i guess? Ofcourse explode would be better if i needed all those other numbers to do something. – Jaskirat Oct 12 '09 at 09:24
  • It's fast enough but just not as fast as simple substring search :) – vava Oct 12 '09 at 09:27
  • Alrite. Modified my answer. Dint want a buggy answer there. Thanks. – Jaskirat Oct 12 '09 at 09:32
  • What if the number is the first or last? Then either the first or second `[^0-9]` will fail. – Gumbo Oct 12 '09 at 09:36
  • Now it is way too similar to gnud's answer. I guess i should remove my answer. Its useless anyway. – Jaskirat Oct 12 '09 at 09:44