By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,424 Members | 1,375 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,424 IT Pros & Developers. It's quick & easy.

comparison string object to string array...

P: n/a
Hi All,

I use Contains method of String object to determine if a string variable
has another string, like that.
***************************
ipAddress.Contains("127.0.0")
****************************

supposing that, there is a string array like

string[] aryIPAddress = {"127.0.0.", "192.168.1.","66.249.71."};

Is it possible to determine if any string in this array occurs in a String
Object without using foreach or for patterns ?

Thanks in advance..
Jul 12 '08 #1
Share this Question
Share on Google+
8 Replies


P: n/a
On Jul 12, 11:38*am, "David Lazos" <D...@DL.comwrote:
I use Contains method of String object to determine if *a string variable
has another string, like that.
***************************
ipAddress.Contains("127.0.0")
****************************

supposing that, *there is a string array like

string[] aryIPAddress = {"127.0.0.", "192.168.1.","66.249.71."};

Is it possible to determine if any string in this array occurs in a String
Object *without using foreach or for patterns ?
If you're using C# 3 and .NET 3.5, you could do:

if (aryIPAddres.Any(candidate =candidate.Contains("127.0.0")))

(You might want to use StartsWith instead of Contains.)

Of course, this still uses for/foreach internally - if you can't
use .NET 3.5 you can easily write your own method to do it.

Jon
Jul 12 '08 #2

P: n/a
On Jul 12, 3:30*pm, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
On Jul 12, 11:38*am, "David *Lazos" <D...@DL.comwrote:
I use Contains method of String object to determine if *a string variable
has another string, like that.
***************************
ipAddress.Contains("127.0.0")
****************************
supposing that, *there is a string array like
string[] aryIPAddress = {"127.0.0.", "192.168.1.","66.249.71."};
Is it possible to determine if any string in this array occurs in a String
Object *without using foreach or for patterns ?

If you're using C# 3 and .NET 3.5, you could do:

if (aryIPAddres.Any(candidate =candidate.Contains("127.0.0")))
If I understand the original poster correctly, he actually wanted to
do it the other way around, that is:

aryIPAddress.Any(candidate =ipAddress.Contains(candidate))

Still, for a sufficiently large list of substrings to match, it's not
so good - since a lookup from beginning to end of the string is done
for every element of the list. In this case, I'd recommend converting
the list of substrings to a Regex, and then use Regex.Match:

var regex = new Regex(string.Join("|", aryIPAddres.Select(s =>
Regex.Escape(s)).ToArray()));
if (regex.IsMatch(ipAddress)) { ... }

It will be somewhat faster, because it will reduce the list of
candidate substrings as it matches - e.g. as soon as it sees that the
first digit is "2", it will not even bother trying to match all IPs
that start with anything else.

Jul 12 '08 #3

P: n/a
On Jul 12, 12:48*pm, Pavel Minaev <int...@gmail.comwrote:
if (aryIPAddres.Any(candidate =candidate.Contains("127.0.0")))

If I understand the original poster correctly, he actually wanted to
do it the other way around, that is:

aryIPAddress.Any(candidate =ipAddress.Contains(candidate))
That's very possible - I wasn't entirely sure which way round it was
meant to be.
Still, for a sufficiently large list of substrings to match, it's not
so good - since a lookup from beginning to end of the string is done
for every element of the list. In this case, I'd recommend converting
the list of substrings to a Regex, and then use Regex.Match:

var regex = new Regex(string.Join("|", aryIPAddres.Select(s =>
Regex.Escape(s)).ToArray()));
if (regex.IsMatch(ipAddress)) { ... }

It will be somewhat faster, because it will reduce the list of
candidate substrings as it matches - e.g. as soon as it sees that the
first digit is "2", it will not even bother trying to match all IPs
that start with anything else.
On the other hand, it has to join all the strings together to start
with, escape them all, and then parse the generated regular
expression.

In addition, the code is considerably more complicated to understand.

I'd certainly go for the simpler way to start with, and then do
concrete performance tests before changing to a regular expression
form.

Of course, if StartsWith is okay, that takes away the inefficiency
anyway :)

Jon
Jul 12 '08 #4

P: n/a
David Lazos wrote:
Hi All,

I use Contains method of String object to determine if a string variable
has another string, like that.
***************************
ipAddress.Contains("127.0.0")
****************************

supposing that, there is a string array like

string[] aryIPAddress = {"127.0.0.", "192.168.1.","66.249.71."};

Is it possible to determine if any string in this array occurs in a String
Object without using foreach or for patterns ?

Thanks in advance..
If the array is sorted (as in your example), you could use a binary
search and a custom comparer, which would be considerably faster than
looping through all the strings.

Something like:

if (Array.BinarySearch(aryIPAddress, ip, new ContainsComparer()) >= 0) {
// ip address found
}

public class ContainsComparer : IComparer<string{

public int Compare(string x, string y) {
if (x.Contains(y) /*or perhaps the other way around*/ ) {
return 0;
} else {
return string.Compare(x, y);
}
}

}

--
Göran Andersson
_____
http://www.guffa.com
Jul 12 '08 #5

P: n/a
On Jul 12, 5:16*pm, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
It will be somewhat faster, because it will reduce the list of
candidate substrings as it matches - e.g. as soon as it sees that the
first digit is "2", it will not even bother trying to match all IPs
that start with anything else.

On the other hand, it has to join all the strings together to start
with, escape them all, and then parse the generated regular
expression.
Oh yes, it largely depends on the specific use case. If those IPs come
from some sort of a config file, and don't change at all (unless the
user explicitly requests config reload, maybe), but are often matched
against a large stream of IP addresses, then regex solution makes more
sense, and then it is probably worth to compile the regex to IL as
well - and this is the kind of scenario I had in mind (HTTP server
matching IPs of incoming requests against preconfigured whitelist/
blacklist which rarely changes, for example). If list of IP masks to
match changes often, then the simple solution will likely be faster.
Jul 12 '08 #6

P: n/a
On Jul 12, 8:53*pm, Göran Andersson <gu...@guffa.comwrote:
David Lazos wrote:
Hi All,
I use Contains method of String object to determine if *a string variable
has another string, like that.
***************************
ipAddress.Contains("127.0.0")
****************************
supposing that, *there is a string array like
string[] aryIPAddress = {"127.0.0.", "192.168.1.","66.249.71."};
Is it possible to determine if any string in this array occurs in a String
Object *without using foreach or for patterns ?
Thanks in advance..

If the array is sorted (as in your example), you could use a binary
search and a custom comparer, which would be considerably faster than
looping through all the strings.

Something like:

if (Array.BinarySearch(aryIPAddress, ip, new ContainsComparer()) >= 0) {
* *// ip address found

}

public class ContainsComparer : IComparer<string{

* *public int Compare(string x, string y) {
* * *if (x.Contains(y) /*or perhaps the other way around*/ ) {
* * * *return 0;
* * *} else {
* * * *return string.Compare(x, y);
* * *}
* *}

}
This won't work, because you'd have to have the array sorted using the
same Comparer as well, and it does not provide a total ordering - for
example, for a given pair of strings A="foobar", B="foo", this
comparer can simultaneously say that A==B, and B<A. To illustrate,
here's a sample set where it will go wrong:

{ "baz", "foo", "foobar" }

A binary search for "bar" using the provided comparer would go like
this:

1. { "baz", "foo", "foobar" }. Pick middle element - "foo". Compare:
"bar" < "foo". Take first half - { "baz" }
2. { "baz" }. Pick middle element - "baz". Compare: "bar" < "baz".
Take first half - { }.
3. { }. Empty set, search unsuccessful.

Whereas, obviously, "foobar" contains "bar", and a proper search would
have found it.
Jul 13 '08 #7

P: n/a
Pavel Minaev wrote:
On Jul 12, 8:53 pm, Göran Andersson <gu...@guffa.comwrote:
>David Lazos wrote:
>>Hi All,
I use Contains method of String object to determine if a string variable
has another string, like that.
***************************
ipAddress.Contains("127.0.0")
****************************
supposing that, there is a string array like
string[] aryIPAddress = {"127.0.0.", "192.168.1.","66.249.71."};
Is it possible to determine if any string in this array occurs in a String
Object without using foreach or for patterns ?
Thanks in advance..
If the array is sorted (as in your example), you could use a binary
search and a custom comparer, which would be considerably faster than
looping through all the strings.

Something like:

if (Array.BinarySearch(aryIPAddress, ip, new ContainsComparer()) >= 0) {
// ip address found

}

public class ContainsComparer : IComparer<string{

public int Compare(string x, string y) {
if (x.Contains(y) /*or perhaps the other way around*/ ) {
return 0;
} else {
return string.Compare(x, y);
}
}

}

This won't work, because you'd have to have the array sorted using the
same Comparer as well, and it does not provide a total ordering - for
example, for a given pair of strings A="foobar", B="foo", this
comparer can simultaneously say that A==B, and B<A. To illustrate,
here's a sample set where it will go wrong:

{ "baz", "foo", "foobar" }

A binary search for "bar" using the provided comparer would go like
this:

1. { "baz", "foo", "foobar" }. Pick middle element - "foo". Compare:
"bar" < "foo". Take first half - { "baz" }
2. { "baz" }. Pick middle element - "baz". Compare: "bar" < "baz".
Take first half - { }.
3. { }. Empty set, search unsuccessful.

Whereas, obviously, "foobar" contains "bar", and a proper search would
have found it.
You are correct, it only works if the comparer uses StartsWith instead
of Contains, which by the look of it might be what the OP is actually
looking for.

--
Göran Andersson
_____
http://www.guffa.com
Jul 13 '08 #8

P: n/a
David Lazos wrote:
Hi All,

I use Contains method of String object to determine if a string variable
has another string, like that.
***************************
ipAddress.Contains("127.0.0")
****************************

supposing that, there is a string array like

string[] aryIPAddress = {"127.0.0.", "192.168.1.","66.249.71."};

Is it possible to determine if any string in this array occurs in a String
Object without using foreach or for patterns ?

Thanks in advance..
Another alternative is to not compare strings at all.

Create an IpRange class that has an upper and lower limit for an ip
range, e.g. 127.0.0.0 - 127.0.0.255. An ip address (at least in ip4) can
be represented as an uint, so checking if an ip address is within the
range would be two integer comparisons. Much more efficient than
comparing strings.

--
Göran Andersson
_____
http://www.guffa.com
Jul 14 '08 #9

This discussion thread is closed

Replies have been disabled for this discussion.