C# 如何修复我的LINQ以从字符串中的列表中正确查找字符串?

C# 如何修复我的LINQ以从字符串中的列表中正确查找字符串?,c#,list,linq,C#,List,Linq,几个小时前,我已经在和LINQ做斗争,LINQ应该从地址列表中的对象列表中查找城市 我有一个CityModel对象列表,其中: public class CityModel { public string City { get; set; } public char CountryChar { get; set; } } 和AddressModel对象列表: public class AddressModel { publ

几个小时前,我已经在和LINQ做斗争,LINQ应该从地址列表中的对象列表中查找城市

我有一个
CityModel
对象列表,其中:

public class CityModel
    {
        public string City { get; set; }
        public char CountryChar { get; set; }
    }
AddressModel
对象列表:

public class AddressModel
    {
        public string Address { get; set; }
        public char CountryChar { get; set; }
    }
addressesM.Add(new AddressModel()
            {
                Address = "#20-06, gateway east, 152, beach road, singapore 189721",
                CountryChar = 's'
            });
            addressesM.Add(new AddressModel()
            {
                Address = "01-01, 8, anthony road, singapore 229957",
                CountryChar = 's'
            }); //note: Anthony
在这两种情况下,
CountryChar
都是属于
城市
地址
属性的国家的第一个字母。所有字符串和字符都是从
ToLower()
解析的,因此它们都是小写的

CityModel
对象的示例:

            cities.Add(new CityModel()
            {
                City = "singapore",
                CountryChar = 's'
            }); //Singapore in singapore
            cities.Add(new CityModel()
            {
                City = "anthony",
                CountryChar = 'u'
            }); //Anthony in United States
AddressModel
对象的两种情况:

public class AddressModel
    {
        public string Address { get; set; }
        public char CountryChar { get; set; }
    }
addressesM.Add(new AddressModel()
            {
                Address = "#20-06, gateway east, 152, beach road, singapore 189721",
                CountryChar = 's'
            });
            addressesM.Add(new AddressModel()
            {
                Address = "01-01, 8, anthony road, singapore 229957",
                CountryChar = 's'
            }); //note: Anthony
我的LINQ的想法是在每个
AddressModel
对象中查找是否有任何城市是我的
Address
属性的子字符串。如果是,则验证
AddressModel的
CountryChar
是否与
CityModel的
CountryChar
匹配

我的林克:

foreach (AddressModel address in addressesM)
            {
                string city = "xxx";
                i++;

                Console.WriteLine(i + " z " + addresses.Count());

                CityModel tocompare = cities.Where(collectionOfCities => address.Address.IndexOf(collectionOfCities.City) >= 0 &&
                (address.Address[address.Address.IndexOf(collectionOfCities.City) - 1] == ' ' ||
                address.Address[address.Address.IndexOf(collectionOfCities.City) - 1] == ',') &&
                (address.Address[address.Address.IndexOf(collectionOfCities.City) + collectionOfCities.City.Length] == ' ' ||
                address.Address[address.Address.IndexOf(collectionOfCities.City) + collectionOfCities.City.Length] == ',') &&
                collectionOfCities.CountryChar == address.CountryChar).FirstOrDefault();

                if (tocompare != null)
                {
                    TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;

                    tocompare.City = textInfo.ToTitleCase(tocompare.City);

                    city = tocompare.City;
                }

                output.Add(city);
            }
对于我的
AddressModel
LINQ的第一种情况,它工作得很好。当我的第二个
AddressModel
里面有一个单词“Anthony”时,问题就出现了,还有一个城市叫
Anthony
。在这种情况下,在检查“Anthony”的其余LINQ条件后,它将添加到我的
输出
“xxx”字符串,并移动到列表中的下一个
地址模型

我不知道在“安东尼”城市失败后该如何做,该计划将测试列表中的其他城市?

编辑:

某些地址可能有包含数字和大写字母的邮政编码,例如:

上海市浦东新区财伦路1690号1-3楼7座, 201203,中国

蒙大拿州鲁西诺镇安托万1号码头6号1楼,邮编98012 卡罗,塞德克斯,摩纳哥

加利福尼亚州西湖村多尔大道1号,邮编:91362-7300, 美国

Gratsos大厦,15号,Eleftheriou Venizelou街,105 64 雅典,希腊

一些城市名称可能有1个以上的单词,例如:

鱼鹰

巴拿马城

拉凡尔纳


首先,让我们组织城市;假设
(City,CountryChar)
组合是唯一的,我们可以构建一个字典:

List<CityModel> cities = ...

Dictionary<(string city, char country), CityModel> citiesDict = cities
  .ToDictionary(item => (item.City, item.CountryChar), 
                item => item);
或更宽松(任何名称将返回
“网关”
“东”
“海滩”
“道路”
“新加坡”
)实施:

IEnumerable<string> CityNames(string address) {
  return Regex
    .Matches(address, @"\b[a-z]+\b", RegexOptions.IgnoreCase)
    .Cast<Match>()
    .Select(match => match.Value);
}
编辑:这里的主要困难是提取潜在的城市名称(一般情况下是自然语言处理…)。如果您能保证地址部分(街道、城市、国家等)用逗号分隔
我们可以尝试
拆分

  IEnumerable<string> CityNames(string address) {
    return address
      .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
      .Select(item => Regex.Replace(item.Trim(), @"\s+", " ").ToLower())
      .Where(item => !string.IsNullOrEmpty(item));
  }

您的解决方案非常有效,谢谢。我想我会喜欢林克的。唯一的问题是当我试图解析包含多个单词的城市名称时。例如新新加坡。如果将
地址
字符串拆分为单独的单词,则会失败。我不确定在这种情况下如何分割地址(更新的问题)。请注意,地址字符串可能包含带有数字和字母的邮政编码。@bakunet:当然,您可以
拆分
(如果您可以保证地址部分由
正确分隔,并且您没有,比如
“37 Nevsky pospect Saint Petersburg”
),实际上,经过编辑后,它工作得非常好。斯帕西巴!
  IEnumerable<string> CityNames(string address) {
    return address
      .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
      .Select(item => Regex.Replace(item, "[0-9]+", ""))
      .Select(item => Regex.Replace(item.Trim(), @"\s+", " ").ToLower())
      .Where(item => !string.IsNullOrEmpty(item));
  }