I've made a method to split address line into separate distinct categories like Region, City, Street and House which are represented by a single class. It follows relatively simple structure.
Address useOther(string Casual, string Other)
{
Address
address = new Address();
List<string>
split = new List<string>();
char[]
separator = { ',' };
split.AddRange(
Casual.Split(
separator,
StringSplitOptions.RemoveEmptyEntries));
split.AddRange(
Other.Split(
separator,
StringSplitOptions.RemoveEmptyEntries));
// Initialize parameters
split = RemoveBannedTokens(split);
for (int i = 0; i < split.Count; i++)
{
(address.Region, split[i]) = findRegionByName(split[i]);
if (address.Region != null)
{
split[i] = split[i].Replace(address.Region.Name, "");
break;
}
}
if (address.Region == null)
{
address.Region = new Region(region);
}
split = ClearSplit(split);
// Finding region
for (int i = 0; i < split.Count; i++)
{
(address.City, split[i]) = findSityByName(split[i]);
if (address.City != null)
{
split[i] = split[i].Replace(address.City.Name, "");
break;
}
}
if (address.City == null)
{
for (int i = 0; i < split.Count; i++)
{
(address.City, split[i]) = findCityByName(split[i], false);
if (address.City != null)
{
split[i] = split[i].Replace(address.City.Name, "");
break;
}
}
}
if (address.City == null)
return address;
split = ClearSplit(split);
// Finding city
for (int i = 0; i < split.Count; i++)
{
(address.Street, split[i]) = findStreetByName(split[i], address.City);
if (address.Street != null)
{
split[i] = split[i].Replace(address.Street.Name, "");
break;
}
}
if (address.Street == null &&
(address.Region.Code.Replace("/", "") +
address.City.Code.Replace("/", "")).Length != 13)
return address;
split = ClearSplit(split);
//Finding street
int
cityIndex = address.City.Index,
streetIndex = address.Street.Index;
for (int i = 0; i < split.Count; i++)
{
split[i] = split[i].Replace("б/н", "");
}
address.House = findNumbers(split.ToArray(), cityIndex, streetIndex);
return address;
}
If you can see repetition goes like this
for (int i = 0; i < split.Count; i++)
{
(address.Something, split[i]) = findSomethingByName(split[i]);
if (address.Something != null)
{
//do this thing
break;
}
}
if (address.Something == null)
//try other thing
split = ClearSplit(split);
I want to avoid this repetition and have something of an array or foreach loop but couldn't find a clear way of making an array with reference values or a foreach reference loop that would work with null values properly. I have thought about making a function with specified inputs and outputs but decide it would only harm ability to read my code, which I'm trying to improve here.