我通过解析带有一些地址的文本文件构建了一个变量。
FileInfo fi = new FileInfo(@"C:\temp\Addresses.txt")
var ZipCodesAndCountryCodes = File.ReadLines(fi.FullName)
.Select(l => new
{
ZipCode = l.Substring(1395, 5),
CountryCode = String.IsNullOrWhiteSpace(l.Substring(1405,30))
? "US"
: l.Substring(1405,30)
});
在此代码中,我用“US”替换国家/地区的任何空白值。但是,如果该国是“美国”或“美利坚合众国”或“美国”,我也想将其标准化为“美国”。我怎么能在LINQ中做到这一点?如果是任何其他国家,则应按原样包括在内。
速度也是一个考虑因素,因为我要解析的文本文件将是800MB左右。谢谢你的帮助。
UPDATE1: 当我尝试Mark和Aush的答案时,我收到了这个错误:
System.ObjectDisposedException: Cannot read from a closed TextReader.
at System.IO.__Error.ReaderClosed()
at System.IO.StreamReader.ReadLine()
at System.IO.File.<InternalReadLines>d__0.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Lookup`2.Create[TSource](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at System.Linq.GroupedEnumerable`3.GetEnumerator()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at AnthemMDTS.Program.Main(String[] args) in c:\Projects\CustomerA\CustomerATax\Program.cs:line 100
这里有什么问题的TextReader?我没有关闭任何东西,代码中也没有任何循环。
答案 0 :(得分:3)
您可以在查询表达式中使用let
子句来存储国家/地区名称Substring()
的结果。
var ZipCodesAndCountryCodes = from line in File.ReadLines(fi.FullName)
let country = line.Substring(1405,30)
select new
{
ZipCode = line.Substring(1395, 5),
CountryCode = ( string.IsNullOrWhiteSpace(country)
|| country=="United States"
|| country=="United States of America"
|| country=="USA")
? "US"
: country
};
答案 1 :(得分:1)
FileInfo fi = new FileInfo(@"C:\temp\Addresses.txt")
var ZipCodesAndCountryCodes = File.ReadLines(fi.FullName).Select(l =>
{
var countrySubstr = l.Substring(1405,30);
return new
{
ZipCode = l.Substring(1395, 5),
CountryCode = string.IsNullOrWhiteSpace(countrySubstr)
|| countrySubstr == "USA"
|| countrySubstr == "United States"
|| countrySubstr == "United States of America"
? "US" : countrySubstr
};
});
答案 2 :(得分:1)
我可能会使用GroupJoin
来使用预定义映射来实质上LEFT OUTER JOIN
。
Dictionary<string, string> mappings = new Dictionary<string, string>()
{
{ "United States", "US" },
{ "United States of America", "US" },
{ "USA", "US" }
};
return ZipCodesAndCountryCodes
.GroupJoin(mappings,
a => a.CountryCode,
b => b.Key,
(a, b) => new {
a.ZipCode,
CountryCode = b.Select(x => x.Value).FirstOrDefault() ?? a.CountryCode
},
StringComparer.CurrentCultureIgnoreCase);
这使您可以轻松添加映射,如果不存在映射,它将默认为当前映射。
这种方法的主要优点是能够修改映射而无需对代码进行大量更改,或者需要维护任何逻辑(确保在逻辑OR之间使用正确的括号等)。
如果你的字面意思是那些是你遇到过的唯一的,那么使用另一种方法可能最容易。而作为之前处理过类似文件的人,我希望还有其他值,你很快就会想要规范化。
答案 3 :(得分:0)
string[] textToSearch = new []{"US","United States","United States of America", "USA"};
FileInfo fi = new FileInfo(@"C:\temp\Addresses.txt")
var ZipCodesAndCountryCodes = File.ReadLines(fi.FullName).Select(l => new
{
ZipCode = l.Substring(1395, 5),
CountryCode = (string.IsNullOrWhiteSpace(l.Substring(1405,30)
|| textToSearch.Contains(l.Substring(1405,30))
? "US"
: l.Substring(1405,30)
});