Does the .NET framework provide a class which will find the item in
the collection with a key which is closest ( greater than or equal,
less than or equal ) to the keys of the collection?
ex: collection keys are 20, 30, 40, 50, 60, 70, 80
find key which is >= 35.
would return the 30 key.
thanks,
Dec 17 '07
22 4728
// Array.BinarySea rch (find next closest match)
Array i2 = Array.CreateIns tance(typeof(st ring), 8);
i2.SetValue("An ne", 0);
i2.SetValue("Bo b", 1);
i2.SetValue("Ch ris", 2);
i2.SetValue("Do nna", 3);
i2.SetValue("El izabeth", 4);
i2.SetValue("Gl enn", 5);
i2.SetValue("Fr anklin", 6);
i2.SetValue("He lene", 7);
int j = Array.BinarySea rch(i2, "DonnaB");
if (j<0)
j = ~j;
MessageBox.Show (i2.GetValue(j) .ToString()); // ==Elizabeth
"Ben Voigt [C++ MVP]" <rb*@nospam.nos pamwrote in message
news:O6******** ******@TK2MSFTN GP05.phx.gbl...
>
"Marc Gravell" <ma**********@g mail.comwrote in message
news:%2******** ********@TK2MSF TNGP03.phx.gbl. ..
>One-way searches are fortunately easier than 2-way proximity... you get to stop sooner ;-p If this is volume usage, then the LINQ approach I posted earlier would be a poor choice (it would sort each time); Ben mentioned a SortedList which may be helpful... I can't only see equality methods myself, but you could perhaps simply walk the list until you find one that is 2022 and return the previous (if you see what I mean...).
Ack! SortedList.Inde xOfKey doesn't return the index for not found items,
while List.BinarySear ch does. But you can't run BinarySearch on a sorted
list! An extension method would be good...
So either reimplement BinarySearch to work on a SortedList or use List and
List.BinarySear ch and keep the list sorted yourself.
>> Of course, if you are adding to the list in sequence, you could just use a regular list, and do the same walk. If you are adding to the list while iterating, it is probably just the last element.
Just for completeness (to contrast to my prior post); in LINQ terms this is:
IDictionary<int , stringdata = new SortedList<int, string{ {20, "a"}, {30, "b"}, {40, "c"}, {50, "d"}, {60, "e"}, {70, "f"}, {80, "g"} }; KeyValuePair<in t, stringresult = data.TakeWhile( x =x.Key <= 35).Last();
(I'm using TakeWhile here since we know the data is sorted; hence it will stop reading when it finds something that doesn't meet the <= 35 condition).
Of course, if you are generally accessing recent data you may be better keeping the list inverted (perhaps even just a List<Tand Insert at 0; or use a custom comparer to automatically invert the list in-place [very easy]) and check for the first match:
KeyValuePair<in t, stringresult = data.SkipWhile( x =x.Key 35).First();
Marc
Ben, Tested that on the original q, as I understand it, the "close
find" shuld give 40 if asked 39...
Array i2 = Array.CreateIns tance(typeof(sh ort),7);
// given 20, 30, 40, 50, 60, 70, 80
i2.SetValue((sh ort)20, 0);
i2.SetValue((sh ort)30, 1);
i2.SetValue((sh ort)40, 2);
i2.SetValue((sh ort)50, 3);
i2.SetValue((sh ort)60, 4);
i2.SetValue((sh ort)70, 5);
i2.SetValue((sh ort)80, 6);
// given 35
int j = Array.BinarySea rch(i2, (short)35);
if (j < -1)
j = ~j-1;
Console.WriteLi ne("35 -" +
i2.GetValue(j). ToString()); // 30
// testing low 10
j = Array.BinarySea rch(i2, (short)10);
if (j < -1)
j = ~j - 1;
else // Oops
j = 0;
Console.WriteLi ne("10 -" +
i2.GetValue(j). ToString()); // 20
// testing high 100
j = Array.BinarySea rch(i2, (short)100);
if (j < -1)
j = ~j - 1;
Console.WriteLi ne("100 -" +
i2.GetValue(j). ToString()); // 80
// testing close 39
j = Array.BinarySea rch(i2, (short)39);
if (j < -1)
j = ~j - 1;
Console.WriteLi ne("39 -" +
i2.GetValue(j). ToString()); // 30 = Fail, should return 40 or what?
//CY
<ch*******@gmai l.comwrote in message
news:1d******** *************** ***********@1g2 000hsl.googlegr oups.com...
Ben, Tested that on the original q, as I understand it, the "close
find" shuld give 40 if asked 39...
that was my doing, not Ben's; yes, you should get 40 if the predicate is
39, and you do; what I'm not clear on is why you're subtracting 1 from the
bitwise complement of the result ... and why you're testing for "j < -1"
if (j < -1)
j = ~j-1;
should be:
if (j < 0)
j = ~j;
BUT, I should have done some bounds checking where the predicate is greater
than the highest valued item in the array:
if (j < i2.Length)
MessageBox.Show (i2.GetValue(j) .ToString());
else
MessageBox.Show ("Cannot return a value");
>
Array i2 = Array.CreateIns tance(typeof(sh ort),7);
// given 20, 30, 40, 50, 60, 70, 80
i2.SetValue((sh ort)20, 0);
i2.SetValue((sh ort)30, 1);
i2.SetValue((sh ort)40, 2);
i2.SetValue((sh ort)50, 3);
i2.SetValue((sh ort)60, 4);
i2.SetValue((sh ort)70, 5);
i2.SetValue((sh ort)80, 6);
// given 35
int j = Array.BinarySea rch(i2, (short)35);
if (j < -1)
j = ~j-1;
Console.WriteLi ne("35 -" +
i2.GetValue(j). ToString()); // 30
// testing low 10
j = Array.BinarySea rch(i2, (short)10);
if (j < -1)
j = ~j - 1;
else // Oops
j = 0;
Console.WriteLi ne("10 -" +
i2.GetValue(j). ToString()); // 20
// testing high 100
j = Array.BinarySea rch(i2, (short)100);
if (j < -1)
j = ~j - 1;
Console.WriteLi ne("100 -" +
i2.GetValue(j). ToString()); // 80
// testing close 39
j = Array.BinarySea rch(i2, (short)39);
if (j < -1)
j = ~j - 1;
Console.WriteLi ne("39 -" +
i2.GetValue(j). ToString()); // 30 = Fail, should return 40 or what?
//CY
"Liz" <li*@tiredofspa m.comwrote in message
news:%2******** ********@TK2MSF TNGP03.phx.gbl. ..
>
<ch*******@gmai l.comwrote in message
news:1d******** *************** ***********@1g2 000hsl.googlegr oups.com...
>Ben, Tested that on the original q, as I understand it, the "close find" shuld give 40 if asked 39...
BinarySearch doesn't give you the closest element by default, it gives you
the address of the closest greater element. The element right before is
(due to sorting) the closest smaller element, and you may therefore use
whichever of the two you prefer. This is still O(log N), because there is
no extra expense as the length of the list increases.
If your list is less than about 64 elements you are better off with a single
pass linear search.
If your elements are fairly evenly distributed (or according to a known
distribution) then you can do much better than a binary search by estimating
the location of the element sought.
>
that was my doing, not Ben's; yes, you should get 40 if the predicate is
39, and you do; what I'm not clear on is why you're subtracting 1 from
the bitwise complement of the result ... and why you're testing for "j
< -1"
>if (j < -1) j = ~j-1;
should be:
if (j < 0)
j = ~j;
BUT, I should have done some bounds checking where the predicate is
greater than the highest valued item in the array:
if (j < i2.Length)
MessageBox.Show (i2.GetValue(j) .ToString());
else
MessageBox.Show ("Cannot return a value");
>> Array i2 = Array.CreateIns tance(typeof(sh ort),7);
// given 20, 30, 40, 50, 60, 70, 80
i2.SetValue((sh ort)20, 0); i2.SetValue((sh ort)30, 1); i2.SetValue((sh ort)40, 2); i2.SetValue((sh ort)50, 3); i2.SetValue((sh ort)60, 4); i2.SetValue((sh ort)70, 5); i2.SetValue((sh ort)80, 6);
// given 35 int j = Array.BinarySea rch(i2, (short)35); if (j < -1) j = ~j-1;
Console.WriteLi ne("35 -" + i2.GetValue(j) .ToString()); // 30
// testing low 10 j = Array.BinarySea rch(i2, (short)10); if (j < -1) j = ~j - 1; else // Oops j = 0; Console.WriteLi ne("10 -" + i2.GetValue(j) .ToString()); // 20
// testing high 100 j = Array.BinarySea rch(i2, (short)100); if (j < -1) j = ~j - 1;
Console.WriteLi ne("100 -" + i2.GetValue(j) .ToString()); // 80
// testing close 39 j = Array.BinarySea rch(i2, (short)39); if (j < -1) j = ~j - 1;
Console.WriteLi ne("39 -" + i2.GetValue(j) .ToString()); // 30 = Fail, should return 40 or what?
//CY
"Liz" <li*@tiredofspa m.comwrote in message
news:uC******** ******@TK2MSFTN GP03.phx.gbl...
>
// Array.BinarySea rch (find next closest match)
Array i2 = Array.CreateIns tance(typeof(st ring), 8);
i2.SetValue("An ne", 0);
i2.SetValue("Bo b", 1);
i2.SetValue("Ch ris", 2);
i2.SetValue("Do nna", 3);
i2.SetValue("El izabeth", 4);
i2.SetValue("Gl enn", 5);
i2.SetValue("Fr anklin", 6);
i2.SetValue("He lene", 7);
<snip>
<off topic>
Why would you declare an array of strings with that syntax?
I mean, it works, but why subject yourself to that icky looking code.
How about
string[] X = new string[]{"Anne", "Bob", "Chris", "Donna", "Elizabeth" ,
"Glenn", "Franklin", "Helene"};
Just curious
Bill
"Bill Butler" <qw****@asdf.co mwrote in message
news:Dikaj.8038 $8y4.8009@trndd c07...
>Array i2 = Array.CreateIns tance(typeof(st ring), 8);
i2.SetValue("A nne", 0); i2.SetValue("B ob", 1); i2.SetValue("C hris", 2); i2.SetValue("D onna", 3); i2.SetValue("E lizabeth", 4); i2.SetValue("G lenn", 5); i2.SetValue("F ranklin", 6); i2.SetValue("H elene", 7);
Why would you declare an array of strings with that syntax?
I mean, it works, but why subject yourself to that icky looking code.
How about
string[] X = new string[]{"Anne", "Bob", "Chris", "Donna", "Elizabeth" ,
"Glenn", "Franklin", "Helene"};
The original question presented was how to get a "soft" match in an array
using BinarySearch, i.e.: if no match, return the next highest value in the
array; so far as I know, there's no (straightforwar d) way to get there from
string[] x = {..,..,.. } syntax ...
who cares about the "ickiness" of syntax? it's all machine code out the
door; in a real-world example, you'd iterate it up with no muss, no fuss in
5-10 lines of code wrapping array.SetValue( a,n) in a loop ... but if you
have a better solution to do the soft match, I'm all ears ... assume the
array would be of significant size, not length = 8 ...
"Liz" <li*@tiredofspa m.comwrote in message
news:Oe******** ******@TK2MSFTN GP04.phx.gbl...
>
"Bill Butler" <qw****@asdf.co mwrote in message
news:Dikaj.8038 $8y4.8009@trndd c07...
>>Array i2 = Array.CreateIns tance(typeof(st ring), 8);
i2.SetValue(" Anne", 0); i2.SetValue(" Bob", 1); i2.SetValue(" Chris", 2); i2.SetValue(" Donna", 3); i2.SetValue(" Elizabeth", 4); i2.SetValue(" Glenn", 5); i2.SetValue(" Franklin", 6); i2.SetValue(" Helene", 7);
>Why would you declare an array of strings with that syntax? I mean, it works, but why subject yourself to that icky looking code.
>How about string[] X = new string[]{"Anne", "Bob", "Chris", "Donna", "Elizabeth" , "Glenn", "Franklin", "Helene"};
The original question presented was how to get a "soft" match in an
array using BinarySearch, i.e.: if no match, return the next highest
value in the array; so far as I know, there's no (straightforwar d)
way to get there from string[] x = {..,..,.. } syntax ...
I did Add "off topic" right before I asked (which you edited out).
I have no quibble over the Binary search suggestion, It is what I would
have suggested.
My question has nothing to do with that.
I simply wanted to know why you would Array.CreateIns tance instead of
the more common syntax for array creation?
Is there some benefit that I am unaware of?
As I said "Just Curious"
Bill
"Bill Butler" <qw****@asdf.co mwrote in message
news:jQlaj.2881 4$JW4.27575@trn ddc05...
>>How about string[] X = new string[]{"Anne", "Bob", "Chris", "Donna", "Elizabeth" , "Glenn", "Franklin", "Helene"};
>The original question presented was how to get a "soft" match in an array using BinarySearch, i.e.: if no match, return the next highest value in the array; so far as I know, there's no (straightforwar d) way to get there from string[] x = {..,..,.. } syntax ...
I did Add "off topic" right before I asked (which you edited out).
I have no quibble over the Binary search suggestion, It is what I would
have suggested.
My question has nothing to do with that.
I simply wanted to know why you would Array.CreateIns tance instead of the
more common syntax for array creation?
Is there some benefit that I am unaware of?
Bill,
First of all, your comment was not off-topic ....
I simply wanted to know why you would Array.CreateIns tance instead of the
more common syntax for array creation?
that's what I responded to .... you can't do this:
string[] X = new string[]{"Anne", "Bob", "Chris", "Donna",
"Elizabeth" , "Glenn", "Franklin", "Helene"};
X.BinarySearch( "DonnaZ");
Do you know a way to initiate a BinarySearch using the array initialization
syntax you propose here?
"Liz" <li*@tiredofspa m.comwrote in message
news:%2******** *******@TK2MSFT NGP03.phx.gbl.. .
>
"Bill Butler" <qw****@asdf.co mwrote in message
news:jQlaj.2881 4$JW4.27575@trn ddc05...
<snip>
Bill,
First of all, your comment was not off-topic ....
>I simply wanted to know why you would Array.CreateIns tance instead of the more common syntax for array creation?
that's what I responded to .... you can't do this:
string[] X = new string[]{"Anne", "Bob", "Chris", "Donna",
"Elizabeth" , "Glenn", "Franklin", "Helene"};
X.BinarySearch( "DonnaZ");
Do you know a way to initiate a BinarySearch using the array
initialization syntax you propose here?
Array.BinarySea rch(X,"DonnaZ") ;
On Wed, 19 Dec 2007 20:13:53 -0800, Liz <li*@tiredofspa m.comwrote:
[...]
>I simply wanted to know why you would Array.CreateIns tance instead of the more common syntax for array creation?
that's what I responded to .... you can't do this:
string[] X = new string[]{"Anne", "Bob", "Chris", "Donna",
"Elizabeth" , "Glenn", "Franklin", "Helene"};
X.BinarySearch( "DonnaZ");
You can't do that even initializing the array as you did. There's no
Array.BinarySea rch() overload that takes a single parameter. There's not
even an instance method version of BinarySearch.
Do you know a way to initiate a BinarySearch using the array
initialization
syntax you propose here?
There are a number of overloads for Array.BinarySea rch. Any of them would
work equally well, whether you initialize the array using the syntax you
posted or the syntax Bill posted. For example:
Array.BinarySea rch(X, "DonnaZ");
I'm with Bill. I don't see any advantage at all to using the syntax you
posted. It's incredibly unwieldy, difficult to read, and doesn't even
provide a typed array. I'm at a loss to understand why you'd prefer that
syntax to the normal array declaration syntax.
Pete This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: panik |
last post by:
Hi,
I have a custom collection that implements CollectionBase. The collection is
called Sensors and contains a list of Sensor objects.
There is the usual index using an integer (Sensors).
Is there a way of using a custom indexer (for example Sensors)
that does *not* need to loop through each item in the collection and compare
them?
|
by: mike |
last post by:
I have ListArray with number in Eg:
1, 1.456, 2.43, 4, 6.78
next i have a decimal variable containing one number EG:
1.786
Could someone please tell me how i find the "closest match" number below the
decimal variable from the arraylist.
Thanks ever so much in advance
|
by: Terry Olsen |
last post by:
I'm using a listview control with 2 columns (in detail view).
I need to find an item by text so that I can add a subitem to it. I haven't
been successful so far.
Any help is appreciated.
|
by: SP |
last post by:
I have created an abstract class inheriting from KeyedCollection<long,
TItemto use as a base class for my collections. In some derived classes I
am providing a new indexer property for the key (long). I need to access my
collection by index and by key however the new long indexer is used for BOTH
int and long, i.e. myCollection will use the long indexer NOT the
base classes int indexer. Why is that? The workaround is to also define a
new...
|
by: Hyun-jik Bae |
last post by:
Is there any way how to get the item which has the most similar key in
key-value collection object such as Dictionary<or SortedDictionary<>
although there is no matching key? If there is none, is there any
substitution class for enabling this?
Please reply. Thanks in advance.
Hyun-jik Bae
| |
by: Jon Slaughter |
last post by:
topic says it all? Is there any simple way? msdn says that the keyed
collection is build from both a sortedlist and sorted dictionary.
http://msdn2.microsoft.com/en-us/library/5z658b67.aspx
(well, it doesn't say that specifically but it says it when talking about
the sorted versions so I'm not sure)
I've found this
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
| |
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |