2015-03-02 2 views
3

У нас есть устаревший пользовательский адресный контроль. Он предоставляет бесплатную текстовую форму, в которую пользователи могут вводить любой адрес, даже неполный или недействительный адрес; см зеленая стрелка на скриншоте:Как определить страну со свободного текстового адреса?

example address control with free text form

Ввод адреса в этой свободной форме текста, чтобы обеспечить лучший пользовательский опыт; однако адрес должен быть структурирован для дальнейшей обработки. Следовательно, адрес анализируется, чтобы определить улицу, город, почтовый индекс, страну и т. Д.

Определить страну кажется довольно простой. Наш текущий (для удобочитаемости упрощенно) Исходный код выглядит следующим образом:

private static string DetermineCountryFromAddress(string fullAddress) 
{ 
    // determine list of countries found in the full address 
    string[] addressLines = fullAddress.Split(Environment.NewLine.ToCharArray()); 
    IList<string> countries = new List<string>(); 
    foreach (string addressLine in addressLines) 
    { 
     // check whether there's a country name hidden in this address line 
     string countryName; 
     if (ContainsCountry(addressLine, out countryName)) 
      countries.Add(countryName); 
    } 

    // if there has been a country found, return the country found last; 
    // otherwise, return the default country (constant) 
    return countries.Any() ? countries[countries.Count - 1] : DefaultCountryName; 
} 

Для любопытства, это как наш упрощенный ContainsCountry() метод выглядит следующим образом:

private static bool ContainsCountry(string addressLine, out string foundCountryName) 
{ 
    // check against all countries 
    foreach (string countryName in 
     AllCountryNames.Where(countryName => addressLine.Contains(countryName))) 
    { 
     foundCountryName = countryName; 
     return true; 
    } 

    // nothing found 
    foundCountryName = null; 
    return false; 
} 

Это решение, хотя не решает эти требования:

  • Страна может быть в любой строке, а не только последний
  • Если ни одна страна не предусмотрено, страна имена, составляющие часть названий улиц, должны быть проигнорированы

Есть ли кто-нибудь, у кого есть умное усовершенствование (решение), которое полностью удовлетворяет одному или двум требованиям? Использование внешнего поставщика услуг для проверки адреса исключается из приемлемых ответов.

+0

Можете ли вы поделиться кодом для функции 'ContainsCountry'? – Nikitesh

+0

Исходный код принципа добавлен в вопрос. Мы просто проверяем, можно ли найти имя страны в адресной строке. –

+0

Как вы его оцениваете? Как у вас есть список стран или вы используете Культуру? – Nikitesh

ответ

2

По мне это наилучшее решение

string[] addressLines = fullAddress.Split(Environment.NewLine.ToCharArray()); 
IList<string> countries = new List<string>(); 

// This will save you a bit of computation, as 90% 
// of country names will be towards the end. 
for (string addressLine in addressLines.Reverse()) 
{ 
    // check whether there's a country name hidden in this address line 
    string countryName; 
    if (ContainsCountry(addressLine, out countryName)) 
     countries.Add(countryName); //Break if a country is found would further reduce the unnecessary iterations. 
} 

Или другой вариант будет использовать Linq

List<string> addressLines = new List<string>(Regex.Split(fullAddress, 
    Environment.NewLine)); 

string countryname = CountryNameList.Where(y => 
    addressLines.Any(z => z == y.countryName)).FirstOrDefault(); 

Вы также можете получить список, если вы используете ToList() вместо FirstOrDefault().

+0

Если вы сортируете адрес в обратном порядке, не могли бы вы просто сломаться, как только вы нашли название страны, вместо добавления в список и затем возврата первого элемента (я предполагаю, что вы вернете первый элемент в вашем случае а не последний элемент, который выполнял ОП)? –

+0

Если бы нам пришлось переломить, зачем использовать список на первом месте? Я тоже думал об этом, но потом не написал его, потому что так было в вопросе. В любом случае, добавьте его в качестве комментария в коде. – Nikitesh

+0

Не забудьте 'Trim()'. – abatishchev

Смежные вопросы