-
Apr 1st, 2017, 09:27 AM
#1
Thread Starter
Lively Member
[RESOLVED] How to address elements in a SortedList Array?
How does one access the elements of a SortedList? The ‘ .Contains’ property does the locating but the second element ‘ .Item’ property yields an error message BC30512: Option Strict On disallows implicit conversions from 'Object' to 'Decimal'. Is there another property to replace the '.Item'?
All of the sample coding I research do not address the second element [Capacity, Count, Add, Clear, Contains,ContainsValue, Item(key), Remove(Key) and RemoveAT(Index)]. TIA JP
Code:
Private PovertyGuidelines As SortedList
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Create Guidelines and intialize beginning values.
PovertyGuidelines = New SortedList From {{"1", "10210"}, {"2", "13690"},
{"3", "17170"}, {"4", "20650"}, {"5", "24130"}, {"6", "27610"}, {"7", "31090"},
{"8", "34570"}, {"9", "38050"}, {"10", "41530"}, {"11", "45010"}, {"12", "48490"}}
End Sub
If PovertyGuidelines.Contains(IndividualHousehold.FamilySize) Then
PovertyLevelDecimal = PovertyGuidelines.Item(IndividualHousehold.FamilySize)
If PovertyLevelDecimal >= IndividualHousehold.IncomeSize Then
-
Apr 1st, 2017, 10:47 AM
#2
Re: How to address elements in a SortedList Array?
SortedList is the non-generic version of the type, so all of its items are of type Object and you have to use a cast operator like CType() if you want to use them as a more specific type.
What you want is the generic SortedList(Of TKey, TValue) class. From the looks of your data, you want SortedList(Of String, String). The generic type parameters tell VB which type to make the key and value properties.
Probably your next problem is it looks like you intend for the values to be Decimal, but for some reason you've specified them as Strings. Is there a reason?
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Apr 1st, 2017, 11:57 AM
#3
Thread Starter
Lively Member
Re: How to address elements in a SortedList Array?
Thanks for the reply. I tried several code changes and missed returning the string to Decimal. Your reply helped me to discover the following code correction:
Code:
CDec(PovertyGuidelines.Item(IndividualHousehold.FamilySize))
and I was able to successfully execute it.Then in a second procedure, I ran into a baffling 'exception handle error' on first if statement having copied the same code into the new procedure. TIA JP
Code:
If PovertyGuidelines.Contains(IndividualHousehold.FamilySize) Then
PovertyLevelDecimal = CDec(PovertyGuidelines.Item(IndividualHousehold.FamilySize))
If PovertyLevelDecimal < IndividualHousehold.IncomeSize Then
' search for households with income below poverty level.
BelowPovertyLevelCountInteger += 1
LoopCountInteger += 1
If MaxIndexInterger = LoopCountInteger - 1 Then
Exit For
End If
End If
-
Apr 1st, 2017, 12:12 PM
#4
Re: How to address elements in a SortedList Array?
Exceptions are like messages from the gods. They have a name, like "IndexOutOfRangeException" that helps you figure out what kind of error you caused. More importantly, they have a message, that will say something like, "The index '3' was not in the array." Most of the time if you read them, it's pretty clear what's going on. Some of them seem a little cryptic until you've seen them a few times.
So you should really post the name of the exception you got, and the message it told you. If you don't understand it, I'm pretty sure someone here can.
One trick: if the exception is "TargetInvocationException", that one is tricky. It's not the real problem. You need to look at its InnerException property. That's the real one. Sometimes THAT'S a TargetInvocationException. Keep going until you find the real exception.
Here's the problem: Contains() is a LINQ method, not one built-in to SortedList. SortedList isn't really a list of your items, internally. It's a list of a type called KeyValuePair. So using LINQ's Contains() with SortedList isn't often very useful. You should really be using the List's ContainsKey() method, which takes the key value. But if you keep using the non-generic type you'll probably find more and more problems.
Here's a quick demo of how I'd set up a SortedList(Of Decimal, Decimal), I think it'd be more handy than what you're doing:
Code:
Imports System
Imports System.Threading.Tasks
Imports System.Collections.Generic
Imports System.Linq
Public Module Module1
Public Sub Main()
Dim sorted As New SortedList(Of Decimal, Decimal) From {
{ 10, 1023456 },
{ 5, 5432 },
{ 8, 891011 }
}
Dim povertyLevel As Decimal = 30000
Dim hasHousehold As Decimal = 10
Dim notHousehold As Decimal = 15
If sorted.ContainsKey(hasHousehold) Then
If sorted(hasHousehold) < povertyLevel Then
Console.WriteLine("Household {0} is below the level!", hasHousehold)
End If
End If
If sorted.ContainsKey(notHousehold) Then
If sorted(notHousehold) < povertyLevel Then
Console.WriteLine("Household {0} is below the level!", hasHousehold)
End If
End If
End Sub
End Module
The more casts you have to do, the harder you have to think about every line. Imagine trying to win a game of checkers if you have glasses that make all the pieces look the same color. You'd have to start every move by asking questions about the color of each piece. That's what programming with non-generic types is like.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Apr 11th, 2017, 01:21 PM
#5
Thread Starter
Lively Member
Re: How to address elements in a SortedList Array?
Thanks for the reply; I had to take a break to accomplish some household chores.
I erred in saying one procedure worked and the other did not - due to wrong procedure call.
I changed my code to using 'ContainsKey', Verified that the index 'IndividualHousehold.FamilySize' was operating coprrectly but again an exception occurs on the sorted array: 'exception {"Failed to compare two elements in the array."} System.InvalidOperationException'. Argument exception: Object must be of type String! I'm at a loss on how work around this exception. TIA JP
-
Apr 11th, 2017, 01:42 PM
#6
Re: How to address elements in a SortedList Array?
I'm at a disadvantage here, you didn't post your new code. If you caused the problem with code similar to your original code, I'm going to repeat myself:
The more casts you have to do, the harder you have to think about every line. Imagine trying to win a game of checkers if you have glasses that make all the pieces look the same color. You'd have to start every move by asking questions about the color of each piece. That's what programming with non-generic types is like.
Everything in your SortedList is of type Object right now. Reality is they're all Strings wearing an Object mask. But it seems like your code really wants to be working with numeric types like Decimal, so you're using cast operators like CDec() here and there to convert when needed.
The exception tells me two pieces of information:
- The failure happened when trying to manipulate the array, because sorting requires comparison.
- The problem is one item was not a String, and another item was a String.
So you probably messed up and tried to add a Decimal, not a String, to the array. This worked, at first, because the rules of the game say anything can wear a mask that makes it an Object. But then the SortedList needed to sort itself, and eventually it had to compare the Decimal to a String. While we, as humans, can come up with sensible answers for how that might work, the rules SortedList follows don't have an answer, so it fails.
The most correct thing to do would be to decide if you want Decimals or Strings and stick with the one you need. Then, you should use SortedList(Of String, String) or SortedList(Of Decimal, Decimal) like I did in #4. That will ensure that if you mess up and try to put the wrong thing in the list, you get a failure at compile time instead of run time, which is easier to figure out and fix.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Apr 11th, 2017, 01:47 PM
#7
Thread Starter
Lively Member
Re: How to address elements in a SortedList Array?
Would I be better served by not using SortedList? If the array { "persons in household" , "household income" } is inserted in sorted sequence by 'persons in household' then I could do a loop search to obtain the poverty level Household Income for comparison the survey data! Or is there a simple code change around my problem? TIA JP
-
Apr 11th, 2017, 01:53 PM
#8
Thread Starter
Lively Member
Re: How to address elements in a SortedList Array?
Thanks for the reply. I will redeclare the sortedlist and see what I run into. Your insight is greatly appreciated. Thanks again. JP
-
Apr 11th, 2017, 02:29 PM
#9
Re: How to address elements in a SortedList Array?
Originally Posted by justphilip
Would I be better served by not using SortedList? If the array { "persons in household" , "household income" } is inserted in sorted sequence by 'persons in household' then I could do a loop search to obtain the poverty level Household Income for comparison the survey data! Or is there a simple code change around my problem? TIA JP
I can't see your code so I can't comment, but my guess is you don't really want either of those things to be Strings. You probably read them in from a file, but they're ultimately numbers so after you get them from the file you should convert them to numbers, THEN put them in the list.
Generally the right steps for dealing with file data is:
- Read the string data.
- Convert the data to a more convenient format.
- Operate on the converted data.
- Convert the data back to strings.
- Write the strings to the file.
If you try to keep it as strings everywhere, it's hard to keep track of when it should be converted to what, and it's easier to make mistakes.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Apr 14th, 2017, 01:12 PM
#10
Thread Starter
Lively Member
Re: How to address elements in a SortedList Array?
Thanks for the reply. I've been stuck on my first array project and am feeling discouraged! The problem is how to load data into a two element structure and be able to address the individual elements.
Code:
Public Structure SurveyData
Public HeadCountDecimal() As Decimal
Public PovertyIncomeDecimal() As Decimal
End Structure
Private MyIndexInterger As Integer
Private MaxIndexInterger As Integer
Trying to load data into Structure SurveyData to effect what the commented out PovertyGuidelines SortList accomplished. Below I attempted two different approaches – both failures. Loading data into this structure should be simple, but the techniques has escaped me. I sure could use a reference on the subject!
Code:
' PovertyGuidelines = New SortedList From {{"1", "10210"}, {"2", "13690"},
' {"3", "17170"}, {"4", "20650"}, {"5", "24130"}, {"6", "27610"}, {"7", "31090"},
' {"8", "34570"}, {"9", "38050"}, {"10", "41530"}, {"11", "45010"}, {"12", "48490"}}
'Dim LHeadCountDecimal(12) As SurveyData
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim LoadSurvey(12) As SurveyData
MaxIndexInterger = 12
Do Until MyIndexInterger > MaxIndexInterger
LoadSurvey.HeadCountDecimal(MyIndexInterger) = (MyIndexInterger)
SurveyData.PovertyIncomeDecimal(MyIndexInterger) = 6730 + 3480 * MyIndexInterger
Loop
End Sub
Errors:
Severity Code Description Project File Line Suppression State
Error BC30456 'HeadCountDecimal' is not a member of 'Form1.SurveyData()'. Programming Exercise 8pt1pt1 D:\Documents\Visual Studio 2017\Projects\Programming Exercise 8pt1pt1\Programming Exercise 8pt1\Form1.vb 53 Active
Error BC30469 Reference to a non-shared member requires an object reference. Programming Exercise 8pt1pt1 D:\Documents\Visual Studio 2017\Projects\Programming Exercise 8pt1pt1\Programming Exercise 8pt1\Form1.vb 54 Active
TIA JP
Last edited by justphilip; Apr 14th, 2017 at 01:21 PM.
-
Apr 14th, 2017, 01:46 PM
#11
Re: How to address elements in a SortedList Array?
LoadSurvey is an array, so to refer to an element within it you need brackets and some kind of number (either hard coded, or using a variable). Any properties/fields of the element (such as HeadCountDecimal) appear after those brackets.
As such, instead of this:
Code:
LoadSurvey.HeadCountDecimal(MyIndexInterger)
...you should have something like this:
Code:
LoadSurvey(1).HeadCountDecimal(MyIndexInterger)
...where 1 should probably be a variable.
You currently have HeadCountDecimal set to be an array each time, which probably isn't what you wanted (based on things above, it seems you want each LoadSurvey to have one HeadCountDecimal and one PovertyIncomeDecimal. If that is the case, remove the brackets from the Structure:
Code:
Public Structure SurveyData
Public HeadCountDecimal As Decimal
Public PovertyIncomeDecimal As Decimal
End Structure
Based on the above and a couple of other assumptions, I think this is how you want Form1_Load:
Code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim LoadSurvey(12) As SurveyData
MaxIndexInterger = 12
For MyIndexInterger = 0 To MaxIndexInterger
LoadSurvey(MyIndexInterger).HeadCountDecimal = MyIndexInterger
LoadSurvey(MyIndexInterger).PovertyIncomeDecimal = 6730 + 3480 * MyIndexInterger
Next
End Sub
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|