1

So i have a string which will be a location such as:
'Lawrence Street, York, YO10 3EU, United Kingdom'
'York, YO10 3EU, United Kingdom'
'Hertford, Hertfordshire, England, United Kingdom'

Etc

However, i would only like to keep the City location and remove the rest, i've used the following code with success however i was wondering is there is a faster method that doesn't need to test each city individually against the string


$location_string = 'York, YO10 3EU, United Kingdom';
$uk_citys = array('York','Hertford','...');

    foreach($uk_citys  as $uk_city) {
     if (strpos( $location_string , $uk_city) !== FALSE){
         $location_string = $uk_city;
     }
Leo Cooper
  • 37
  • 5
  • Faster than what ? (P.S. there are only [76](https://www.google.com/search?q=how+many+cities+are+the+in+the+united+kingdom) cities in the United Kingdom.) – Luuk Mar 25 '23 at 15:43
  • You can use `break`, to make it slightly faster (see: [break out of if and foreach](https://stackoverflow.com/questions/9215588/break-out-of-if-and-foreach)) – Luuk Mar 25 '23 at 15:55
  • You've entered 3 different data formats. In one of them city is on the 2nd position, in two of them it's on 1st position. Is there any way you could reliably say which position will be occupied by city? If yes, then you could parse these strings and just it up. – Zbigniew Mar 25 '23 at 17:29
  • I assume you'll want to match case-insensitively? and with word boundaries? If the city is always before the first comma, then the task becomes much simpler. – mickmackusa Mar 26 '23 at 21:55

1 Answers1

1

Even if you can do exactly the same with arrays and array_intersect, this is the opportunity to use the ds module and the Set class:

$cities = new \Ds\Set([
    'birmingham', 'bradford', 'brighton and hove', 'bristol', 'cambridge',
    'canterbury', 'carlisle', 'chelmsford', 'chester', 'chichester', 'colchester',
    'coventry', 'derby', 'doncaster', 'durham', 'ely', 'exeter', 'gloucester',
    'hereford', 'kingston upon hull', 'lancaster', 'leeds', 'leicester',
    'lichfield', 'lincoln', 'liverpool', 'london', 'city of london', 'manchester',
    'milton keynes', 'newcastle upon tyne', 'norwich', 'nottingham', 'oxford',
    'peterborough', 'plymouth', 'portsmouth', 'preston', 'ripon', 'salford',
    'salisbury', 'sheffield', 'southampton', 'southend-on-sea', 'st albans',
    'stoke on trent', 'stoke-on-trent', 'sunderland', 'truro', 'wakefield',
    'wells', 'westminster', 'city of westminster', 'winchester', 'wolverhampton',
    'worcester', 'york', 'aberdeen', 'dundee', 'dunfermline', 'edinburgh',
    'glasgow', 'inverness', 'perth', 'stirling', 'bangor', 'cardiff', 'newport',
    'st asaph', 'st davids', 'swansea', 'wrexham', 'armagh', 'belfast', 'lisburn',
    'derry', 'newry']);
    
$location = 'Lawrence Street, York, YO10 3EU, United Kingdom';

$locaSet = new \Ds\Set(preg_split('~\s*,\s*~', strtolower($location)));

$inter = $cities->intersect($locaSet);

if (!$inter->isEmpty()) {
    echo $inter->get(0); // york
}
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
  • This technique is new to me. Please park it on a page that will have a better chance of surviving. Stack Overflow readers are best served when all of the techniques for a given task are all in one place. – mickmackusa Mar 26 '23 at 21:53