Determine which number is closer HOW?

vbMarkO

Centurion
Joined
Aug 19, 2005
Messages
157
I want to do 3 things

Dim myArr() As String = {"6200", "6600", "7900", "8600", "9900"}

myInt = "7700"

1 .How do I determine which integer in myArr is closest to myInt
2. Next Closest
3. Next closest

First closest txt1. text = myArr(i) & " 1st in line"
2nd txt2.text = myArr(i) & " 2nd in line"
3rd txt3.text = myArr(i) & " 3rd in line"

I gave an attempt at this but I am embarrassed to show it as it didnt work and it was terrible

Any help is much appreciated

vbMarkO
 
Could you not just loop over the array and subtract the value from myInt and then calculate the absolute value (i.e. ignore the sign), then store this value / original value in a dictionary - the lowest value is the closest etc.
 
Yes .... but then this is why I asked .. I am som how over looking the obvious ... I was sort of hoping somon might post an example .... just point me the way ..
I mean I get it .... Here is the psuedo code or at least my thoughts

myInt = "7700"
Loop through array
FOr Each item in array
If item > myInt Then
' Then those that are greater than myInt
' subtract myInt from them ie; 8700 - 7700 = 1000 and 8800 - 7700
' = 1100 or finally 9700 - 7700 = 2000

' Then somehow compare the results to determine which of the items
' that are greater are closest
' Then do the same to the other side except this time subtract
' those items in the array that are less than myInt from myInt
' ie; 7700 - 6700 = 1000 an so on

' Then compare the results of each side as to which are closest

'OK as you can see I got an idea but I know I am going way off base here I can feel it I am simply ovrlooking the obvious or the simple solution

Also I am wanting as I said to list the 1st closest to the 3rd closest
but what happens if 2 are the same distance away????
Next

Help is apreciated
 
Visual Basic:
        Dim myArr() As String = {"6200", "6600", "7900", "8600", "9900"}
        Dim myInt As Integer = 7700

        Dim ClosestInt As Integer = Math.Abs(CInt(myArr(0)) - myInt)
        Dim usedArr As Integer = 0

        For i As Integer = 1 To myArr.Length - 1
            Dim TempInt As Integer = Math.Abs(CInt(myArr(i)) - myInt)
            If TempInt < ClosestInt Then
                ClosestInt = TempInt
                usedArr = i
            End If

        Next

        MessageBox.Show(String.Format("Closest number: {0:#,0}", CInt(myArr(usedArr))))
 
This code is almost perfect but it does have one problem but then that might be my fault as you wrote it to search what I put in my array example

I tested it and it found 7900 which in the example is correct its closest but put two numbers that are just as close then it chooses only one

I added another number I put 7600 in and changed the 7900 to 7800 the code returned 7800 as closest but in fact the 2 are the same distance away ..

Ok now let me share what it is I am doing and why ..... I am writing a program that monitors all the police calls iin my area. In fact that part is done and it works great .... the addresses of the calls are stripped and entered into arrays ... like the one I showed you there is a south array for the address containing IE; 7500 S ST, 8600 S another ST
The other array is for East 1500 E you get it ST
Anyway, I am highlighting in an RTB the calls that are within 2 miles of a specific address .... it is to assist us in keeping an eye on certain calls of conern in our area.

So this is why ... thanx for the code by the way I will see if I can figure out how to get adresses that are closest and or also determine those that are equally as close.

Mark
 
Excellent a chance to show off with Linq!!

The following snippet will return a collection of numbers sorted by how far from the starting number - just check the output window when running under a debug build to see the output.

Visual Basic:
        Dim myArr() As String = {"6200", "6600", "7900", "8600", "9900"}
        Dim myInt As Integer = 7700

        Dim res = From nums In myArr _
                  Order By Math.Abs(Convert.ToInt32(nums) - myInt) _
                  Select New With {.Original = nums, .Difference = Math.Abs(Convert.ToInt32(nums) - myInt)}

        'just print out to debug as an example
        For Each x In res
            Debug.WriteLine(String.Format("Number {0}, distance {1}", x.Original, x.Difference))
        Next
although it would be easier still if the original array contained integers rather than strings.

If you need to handle multiple numbers being the same distance then something like
Visual Basic:
     Dim myArr() As String = {"6200", "6600", "7900", "7500", "8600", "9900"}
        Dim myInt As Integer = 7700

        Dim res = From nums In myArr _
                    Let diff = Math.Abs(Convert.ToInt32(nums) - myInt) _
                    Order By diff _
                    Group nums By diff _
                    Into DistanceGroup = Group _
                    Select New With {.Difference = diff, .NumberOfMatches = DistanceGroup.Count, DistanceGroup}


        'just print out to debug as an example
        For Each x In res
            Debug.WriteLine(String.Format("Distance {0}, Number Of Matches {1}", x.Difference, x.NumberOfMatches))
            For Each number In x.DistanceGroup
                Debug.WriteLine(String.Format("Original number {0}", number))
            Next
        Next

which returns a collection of objects giving the distance (closest to furthest, number of matches and then a list of the actual numbers) - the dubug stuff at the end should show you what can be done to get at this. Again if the original array was converted to integers things would be a little easier.
 
Just to make things even more complex the following two examples use the joys of lambda expressions to convert the strings to integers on the fly...
Visual Basic:
        Dim myArr() As String = {"6200", "6600", "7900", "8600", "9900"}
        Dim myInt As Integer = 7700

        Dim res = From nums In myArr.Select(Function(s) Convert.ToInt32(s)) _
                  Order By nums - myInt _
                  Select New With {.Original = nums, .Difference = nums - myInt}

        'just print out to debug as an example
        For Each x In res
            Debug.WriteLine(String.Format("Number {0}, distance {1}", x.Original, x.Difference))
        Next
and
Visual Basic:
        Dim myArr() As String = {"6200", "6600", "7900", "7500", "8600", "9900"}
        Dim myInt As Integer = 7700

        Dim res = From nums In myArr.Select(Function(s) Convert.ToInt32(s)) _
                    Let diff = Math.Abs(nums - myInt) _
                    Order By diff _
                    Group nums By diff _
                    Into DistanceGroup = Group _
                    Select New With {.Difference = diff, .NumberOfMatches = DistanceGroup.Count, DistanceGroup}

        'just print out to debug as an example
        For Each x In res
            Debug.WriteLine(String.Format("Distance {0}, Number Of Matches {1}", x.Difference, x.NumberOfMatches))
            For Each number In x.DistanceGroup
                Debug.WriteLine(String.Format("Original number {0}", number))
            Next
        Next
 
Here is the code modified sort o just made it fit what I already have but .... I havent figured out yet how to compare the final results to then determine the address closest to farthest away

I am putting th whole thing in so you can see what I am trying to do
Note I am only pulling out South addresses here .... I tried to start with one side then do the other the East addresses

Its like this
|_7100 S_______|3000 E
|
|
|_8100 S_______|3000 E
|
|
|_9100 S_______|3000 E

This very crude map above gives an idea of what I am shooting for
location is just below 81st S .... we can call it 8100 anyway
I am logging various crime activity within a 2 mile radius so to speak
2 miles North of 8100 which my map above only shows 1 mile
but then also 2 miles E and it dos reflect aprox 2 miles

The addresses are in an array in the above format .....

my thoughts or approach maybe the wrong way ... maybe there is an easier way to figure coordinates ... but my idea was simply to find the smallest number south or north of 8100 then East of 8100 .... no need to wory about W as I am against the river .....

Code:
Dim addArr() As String = {"6100 S Lewis Ave", "4100 S Yale Ave", "3900 E 28 ST S", _
                                  "2100 S Jackson Ave", "3100 S Yale Ave", "7800 S Jamestown Ave", _
                                  "1900 E 49 ST S", "2400 S Maybelle Ave", "7600 S Jamestown Ave", _
                                  "2400 E 71 ST S", "9800 S Lewis Ave", "6300 S Riverside Pkwy"}

        For sIn = 61 To 100
            For Each item In addArr
                If item.Contains(sIn & "00 S") Then
                    'lstS.Items.Add(item)
                    Dim myInt As Integer = "7700"
                    'Dim sArr As New ArrayList
                    
                    If item.Contains(sIn & "00") Then
                        item = Microsoft.VisualBasic.Left(item, 4)
                        '////////////NEW PARSE CODE HERE

                        Dim sNumArr As New ArrayList
                        sNumArr.Add(item)

                        Dim sInt As Integer = 7700

                        Dim res = From nums In sNumArr _
                                    Let diff = Math.Abs(Convert.ToInt32(nums) - sInt) _
                                    Order By diff _
                                    Group nums By diff _
                                    Into DistanceGroup = Group _
                                    Select New With {.Difference = diff, .NumberOfMatches = DistanceGroup.Count, DistanceGroup}


                        'just print out to debug as an example
                        For Each x In res
                            ' Debug.WriteLine(String.Format("Distance {0}, Number Of Matches {1}", x.Difference, x.NumberOfMatches))
                            lstE.Items.Add(String.Format("Distance {0}, Number Of Matches {1}", x.Difference, x.NumberOfMatches))
                            For Each number In x.DistanceGroup
                                'Debug.WriteLine(String.Format("Original number {0}", number))
                                lstS.Items.Add(String.Format(String.Format("Original number {0}", number)))
                                ' Below rtb1.text I put to se what it looked like compared to lsitbox items
                                ' Its letting m know in the first for each ... smallest distances and largest distances
                                ' Now I am trying to figur out how to return 1. smallest distance (which is closest)
                                '............................................2. next small and so on ....
                                ' this does at last give me the distances to compare ... thank you I do appreciate that
                                rtb1.Text = rtb1.Text & number & vbCrLf

                            Next
                        Next



                    End If
                    



                End If
            Next
        Next
 
As a quick one - the objects returned in my above post are sorted from closest to furthest away - if you loop over them (e.g. for each) you should be getting further away each time.

From the addresses is it only the first part needed i.e. the number followed by S / E or N?

Could the point of reference change from the hard coded 7700 and how are E address compared to this point?

Would it be possible to simply map the street nummbers to a simple 2d grid and use that to calculate distances?
 
Yes, I like the idea ... already on to it ... in fact I am playing with it right now ... I have put together a high res map to work with ... the map covers a little more than the area I am concerned with but then thats ok ...


Adresses here in Tulsa are the easiest in the world I think ...

|
|
|
___|____
|

The Dashed line Up & Down is north and South 8100 of course is 81 blocks from
Admiral which is the dividing line for north south

anyway then east from Riverside which at 8100 S starts at 1800 Block E

Riverside is aproximately 1800 E
81 Street is 8100 S
On my image the coordinates are 400, 916
400 is equal to 1800 E
916 is 8100 South

WHat I would like to be able to do is determine how figure the math here as to how to calculate the coordinates
If the 1800 block of 81st = 400, 916 then what would
3300 block of 81st = ?, 916

Oh and your code ... I am working with it now to loop through ... I will let you know how it turns out as soon as I have the direction I am going to take it

Mark
 
Back
Top