Reputation: 2291
I have a LINQ query and I want to have addresses between a range of zipcodes from 1000 to 2000.
How do I find if the zipcode with a value "3456 AB"
(I only check the 4 first characters) exists of only digits?
var address = address.Where(p => p.Zipcode != null
&& p.Zipcode.Length > 4
&& p.Zipcode.Substring(0, 4).Isnumber()
&& Convert.ToInt32(p.Zipcode.Substring(0, 4)) > zipcodeFrom);
Upvotes: 1
Views: 3098
Reputation: 2036
You should just use TryParse, it returns bool if the string is convertable to an int.
Some dummy data to test on:
var addresses = new[]
{
new { Zipcode = "3456 AB" }, // These of course have other fields,
new { Zipcode = "345678" }, // but in this example we only care
new { Zipcode = "876543" }, // about Zipcode
new { Zipcode = "X3456" },
new { Zipcode = "5000 GG" },
};
The query:
int zipcodeFrom = 4000;
int parsedZipcode;
var qualifiedAddresses = addresses
.Where(p => true
&& p.Zipcode != null
&& p.Zipcode.Length >= 4
&& int.TryParse(p.Zipcode.Substring(0, 4), out parsedZipcode)
&& parsedZipcode > zipcodeFrom
);
Output:
876543
5000 GG
Upvotes: 2
Reputation: 2291
Thank you for all your answers. I have tried it all.
Maybe it's LINQ-to-SQL. But all functions as All, char.IsDigit and Regex.Match doesn't work. The "table" from SQL Server was a view. So I changed the view for an extra field ZipcodeInt.
var address = address.Where(p => p.Zipcode != null
&& p.Zipcode.Length > 4
&& p.ZipcodeInt > zipcodeFrom);
Upvotes: 0
Reputation:
You can match a 4 digits string and parse it.
var resultString = int.Parse(
Regex.Match(zip, @"\d{4}").Value
);
If you want the Linq equivalent
var linqEquiv = zip.Select((c, i) =>
String.Join("",zip.Skip(i).Take(4))).FirstOrDefault(zip =>
{ int i; return int.TryParse(zip, out i) && i >= 1000 && i <= 2000 ; });
Finally, with your class definition
var linqEquivalent = address.Where(a => a.ZipCode.ToArray().Select((c, i) =>
String.Join("", a.ZipCode.ToArray().Skip(i).Take(4))).FirstOrDefault(zip =>
{ int i; return int.TryParse(zip, out i) && i >= 1000 && i <= 2000; }) != null);
with the following list
var address = new List<Address>() {
new Address() { ZipCode = "123 cap 1567 AB 6666" }, // 1567 matches conds
new Address() { ZipCode = "123 cap 4567 AB 6666" },
new Address() { ZipCode = "123 cap 4567 AB 1666" } }; // 1666 matches conds
linqEquivalent
will contain the first and the third address.
Upvotes: 1
Reputation: 2742
var valid = addresses
.Where(a =>
a.Zipcode != null
&& a.Zipcode.Length > 4
&& a.Zipcode.Substring(0, 4).All(char.IsDigit))
.Select(a => new { Address = a, Zipcode = Convert.ToInt32(a.Zipcode.Substring(0, 4)) })
.Where(a => a.Zipcode >= 1000 && a.Zipcode <= 2000)
.Select(a => a.Address);
Keeping your original checks in - firstly we filter out all addresses where Zipcode is null, is less than 4 in length, or the first 4 characters are not all digits.
The we project a new sequence of an anonymous type containing the address and the 4 digit Zipcode as an int. We can then filter this collection by checking if the int Zipcode is within the range we require. Finally we return the original addresses.
Upvotes: 1
Reputation: 9650
You may use Regex to check if the first four chars represent a number from 1000 to 2000. This would simplify your expression significantly:
var address = address.Where(p => p.Zipcode != null
&& Regex.Match(p.Zipcode, @"^[12]\d{3}").Success);
Upvotes: 3
Reputation: 2885
int intzipcode;
var address = address
.Where(p => true
&& p.Zipcode != null
&& p.Zipcode.Length > 4
&& int.TryParse(p.Zipcode.Substring(0, 4), out intzipcode)
&& Convert.ToInt32(p.Zipcode.Substring(0, 4)) > 1000
&& Convert.ToInt32(p.Zipcode.Substring(0, 4)) < 2000
)
Upvotes: 0
Reputation: 37000
For example:
var valid = adress.Where(x => x.ZipCode != null)
.Select(x => x.ZipCode)
.Where(x => x.Take(4).All(Char.IsDigit));
The Where
-clause checks the four first characters of every ZipCode
to be all numbers. Be aware that when using Take(4)
you will get an enumeration of type char
, not just a string. Thus you can simply call x.IsDigit
to check if the character represents a number.
Upvotes: 1