ā C# Arrays/Switch case help
Hi guys,
I was just wondering if anybody here would be willing to potentially message me or hop in a voice call if they know a solution to my issue.
The issue is as follows:
Basically, I currently have a menu system that asks the user for an input, I then have a 2D array consisting of information that will be displayed depending on the user's input,
However, I am currently using a switch case like case "1" do this, case "2" do that, and this approach is for 8 different scenarios and thus is around 160lines long of just repeated console.writeline jargon. Since the user input is equal to one of the elements of the array, I was wondering if there was a shorter way of writing this so that my code would detect the user input, match that to its corresponding element in the array, and then print every element of said array.
If anybody could think of a solution and help me I would seriously appreciate it.
164 Replies
I think if you provide a small minimal code sample that illustrates what you are currently doing it will be easier for people to suggest a better way, if one exists.
and then it just goes on like that for every planet name when it is inputted,
Use $code to share code samples, those screenshots are pain
To post C# code type the following:
```cs
// code here
```
Get an example by typing
$codegif
in chat
For longer snippets, use: https://paste.mod.gg/$code
To post C# code type the following:
```cs
// code here
```
Get an example by typing
$codegif
in chat
For longer snippets, use: https://paste.mod.gg/ok shall i send my whole code there isnt much more really or do u want the same snippets from the ss
When you have repeated code like that that only changes slightly, you should turn it into a function (method) so you can re-use it.
Sure, send the entire code
I'm not sure a 2D array is a very good choice of data structure.
oh how come
what do u suggest
Use $paste
If your code is too long, you can post to https://paste.mod.gg/ and copy the link into chat for others to see your shared code!
BlazeBin - sragjyveqzdp
A tool for sharing your source code with the world!
Hard coding array indexes like that is a very fragile way to approach things.
hmm
how else do u reckon i should store that info then?
but i cant read or write to a file btw so storing it in a file isnt an option
You seem to know how to create classes. Have you considered making a class that holds planetary data, then instantiating that class once per planet?
so
like
make an entirely seperate class just for the planetary data
and then depending on user input, displaying the corresponding section of that class that will show the right data?
You can use a dictionary to lookup the planet based on the user input
i see
(You could also just use strings if it suits your purpose rather than actual types, but in a real world application where you are representing something like the mass of a planet you should probably use numeric types so you can do comparisons and calculations.)
yeah
i want them to be the 'correct' data type
Well, see if you can implement mtreits suggestion then
if you get stuck, tell us where and how
i have never used dictionaries before so this will be good practice then
yep! its a lookup table, one key for one value
Also in a real world application you would probably have a Moon type and then instead of NumberOfMoons the planet would have a List of Moon objects with things like the mass of the moon, etc., although that's perhaps going too far down the rabbit hole for this particular program / assignment.
yeah but the problem with that was some planets have like 40 moons so its a lot of data
so i chose to do number
40? rookie numbers
š
and then if user queries data i would display some of the more promeneint moons i suppoes
haha
Jupiter has a varying number of moons, iirc
between 90 and 104 or something
yeah something like that
ok guys thanks for the advice, i will try change the program now and use a dictionary to see how this makes things
Also, functions are your friend!
just to check, is PlanetInfo() an example of a function
or is that a method
For instance, in your original example:
This is opaque (not immediately clear what it's doing) and repeated many times, so a better approach would have been to write a small helper function:
Functions and methods are the same thing in C#
ah ok
Function is just the more general programming term.
gotcha
Method is basically a function associated with an object and/or type.
so here
are u saying i should make a helper function that will output the header above each piece of data, rather than using the Console.WriteLine(planetArray[0, arrayNumber]); idea
Yes, then when you see this in the code:
...it's more clear what that line of code is doing.
In this case you're only saving a single line of code but in fact your could use the same technique for other places where you are doing the same thing repeatedly.
nice
thank you
i will implement that
@sebt for the sake of argument let's say you wanted to keep your original 2D array implementation. Consider how much easier something like this would be to read than your original code...
That's where encapsulating code into methods starts to help...
what is the deal with the $ sign in the default consolewriteline
i see it a lot
but dont know what it actually does
$interpolation
String interpolation is the preferred way of building strings in C#. It is easier to read than concatenation.
For example:
can be written as:
thank you haha
so when the $ sign is htere it lets the code know that some interpolation is gonna go down
Technically you can put the $ and not include anything to actually interpolate, in which case it's sort of pointless but it's technically allowed.
but you cant interpolate without the $
right>
Correct
nice
The $ tells the compiler to do the string interpolation, just in case it's not clear.
yhyh
ive just tried implementing a helper function along with a switch case whilst still using the 2d array idea
i think im just gonna go with dictionaries lool
I use dictionaries constantly. I've never used a 2D array at work.
oh damn
I guess they are helpful if you are representing things like a matrix or a grid for a game or something but the kind of work I do doesn't involve that kind of thing. I think the first time I used a 2D array was last year during AdventOfCode.
Why not create a
Planet
class?well i had actually only used 1d arrays so i wanted to try with 2d arrays for this application
what do u mean create a planet class
to hold all information?
That's what I showed earlier...
https://discord.com/channels/143867839282020352/1167601239308120175/1167605303102148689
mtreit
Quoted by
<@406536255426396160> from #C# Arrays/Switch case help (click here)
React with ā to remove this embed.
what is record
ive never seen it before
(records are just classes but with some stuff auto-implemented for you.)
oh
haha
If you have types that just hold data, records are nice and succinct.
True, I often forget they exist as I'm used to classes
ok i will use record then for this
You can see here what the record syntactic sugar actually gets expanded to by the compiler:
https://sharplab.io/#v2:D4AQTAjAsAULBOBTAxge3gEwAQAUA2AhgHaIAuAFCBAAxYByBAtogDRYaoCuARnolgFkCAZ2FsAlkVJYAIuOGliyVlknS6nRt0TwA8gDMBqVEWEBKANxA===
SharpLab
C#/VB/F# compiler playground.
i have no idea what im looking ath
haha
ahh
so with record
i have the things like no. moons, planet name, mass etc all defined already with the correct data types
so when it comes to implementing in the dictionary it already knows what data type each thing is and what it actually represents
and thats also why its better to use dictionaries than arrays
dictionaries are cool bro
Well, you can have an array of planets as well
Dictionaries give you a nice way to fetch a given record by some key.
so much nicer
Planet[]
but dictionaries make retreiving data nicer than arrays it seems
In some cases, yes
in this case i mean
Dictionaries can have (mostly) anything be the key
So, yes
You can get
allPlanets["jupiter"]
for example
While with an array you would have to somehow remember, or print it to the user, that Jupiter is stored at index 7 or so
Unless... you were to use LINQ
allPlanets.Where(planet => planet.Name == "jupiter").Single()
for examplewhat is LInq
I See it mentioned a lot
did i just commit a sin by asking that
Could also just have a
Single
with a predicate I believeNo, @ZZZZZZZZZZZZZZZZZZZZZZZZZ commited a sin by writing that code.
oh ok
Right, true. My EF habits are showing lol, I like the condition to always be first
(linear search to look things up in a list or array is very slow compared to using a dictionary, which has constant time lookup)
LINQ has it's uses but using it to look things up in a list is generally not one of it's better use cases.
ok im gonna pretend it doesnt exist then for now
yeah but the difference is minimal no?
nano seconds!
If you call 4,000 times slower minimal
yeah thats true but if u had them both side by side i dont think i could honestly tell if its in nanoseconds
500 million nanoseconds is half a second
yo
im just making this dictionary now
and for some of the planets the distance is billion rather than million km away
and im getting an error saying cannot convert from long to int
shall i change distance from int to long then
int is limited to 2^32 or a little over 4 billion. If you need numbers larger than that, you want a 64-bit integer instead of a 32-bit integer. (
long
is the C# name for a 64-bit integer.)yeah
Could always try using an
uint
ive never had to use such big numbers before thats why i was unfamilar with it
but yeah im gonna use long rather than int
because i need to
But, yeah, long will probably be safer
That's still limited to 4 billion (int is actually limited to 2 billion since it's signed.)
really
my value is > 4 bil
and im not getting an error
long
it isAngius
REPL Result: Success
Result: <>f__AnonymousType0#1<int, uint, long, ulong>
Compile: 499.957ms | Execution: 119.831ms | React with ā to remove this embed.
wow
ah i see
wow ulong is huge
18 quintillion...
hmm i made a dictionary
and put it within a record
but i dont know how to access elements of it based upon userinput
Don't put the dictionary inside the record
is that because i will have trouble accessing it
That
And because there's no reason to do that
Well, no, but...you're creating a copy of that dictionary inside every planet.
And because you create a cyclical dependency
That's just wasting memory
ah ok
whats the point of the record then
is that where i should put a method for accesing the elements within the dictionary?
No
The point is to group up all the properties of the planet
It's the basis of any object-oriented programming language
Objects
hmm ok
so where do u think is best to store the dictionary
In programming you have data and code that operates on data. Records (classes) are how you define data in a structured way.
You can just make the dictionary a static field of your class like you did with the array you were using previously.
ah ok
Or put it in it's own class...
Lots of ways to organize things.
i think i prefer to put it in its own class
yeah thats ive done
i put the dictionary in its own class
so now how do i access elements from the dictionary in a way that uses less lines of code than before when i incorporated the array?
and display to the user
theDictionary[key]
i cant access it
Why?
so lets say i just try output it with a console write lien
when i type the name of the dictionary which is planetInfo
it says not defined in current context
Well... is it defined in the current context?
$scopes
thing a
is available in scope A
and scope B
thing b
is available only in scope B
yeah i think so
i cant see why it is having problems accessing it
@sebt show your latest code
ok but ofc it is very wip
You probably didn't make it public or something.
BlazeBin - dumealmqqfkb
A tool for sharing your source code with the world!
Yeah the planetInfo field is not public.
Also, you should make it a property not a field.
how do i do that
also i tried making public but vs said its 'inconsistent accessibility'
and gave an error
Something like that
Inconsistent accessibility is because your Planet record is private.
Make it public or internal
Basically you can't return a private class from a public member
ahh
i gotcha
and it references planet ofc so it had to also be public
Yeah
Also, protip, dictionary has an alternative syntax you might find cleaner:
And/or you can use a target-type
new
to not have to repeat new Planet
everywhere
hmm ok i see
and when i print a line from dictionary
is there a way to get rid of the curly braces
and make it a bit neater to the user i suppose
I would probably rename the dictionary to just
Planets
, so you do PlanetData.Planets
, a bit less redundant.
So, that's what using record
does, it implements ToString for you.
If you want a different string representation, you can override ToString yourself.Or manually interpolate the properties of the record
so how do i put the record into action
right now im just doing console.writeline(PlanetData.PlanetInfo["mercury"]);
With a
var planet = PlanetData.PlanetInfo["mercury"]
beforehand
Example of overriding ToString
Or like that, yeah
ahh nice man
im learning so much
thanks u guys
so once i have overriden it
does that mean whenever i output something from that dictionary with a name mass distance and no.moons
the code knows to output it exactly as i have told it do
Angius
REPL Result: Success
Console Output
Compile: 697.149ms | Execution: 72.227ms | React with ā to remove this embed.
whats the deal with the variable f
It's just a variable
yeah but
why put it into a variable
then output that
I mean, sure, I can just not
Angius
REPL Result: Success
Console Output
Compile: 677.522ms | Execution: 110.834ms | React with ā to remove this embed.
That also works
yeah
i dont see the point of making a new variable when u can just output it directly and its the desired outcome
but i suppose it can be easier to read
It often helps with debugging
yeah
this is weird tho to me
because i dont even mention the record
but when i do
Console.WriteLine(PlanetData.PlanetInfo["mercury"]);
it is in the layout that is specified in the record
automatically
The one specified in
ToString()
override?
Well, yeah
PlanetInfo
is a dictionary of <string, Planet>
When you get an item out of it, that item will be of type Planet
ahh i see
Planet
has a ToString()
override
And it will be used to... convert it to a stringso if i put the method outside of the planet record then it wouldnt automatically convert it
right?
Correct
ok cool
See that
override
?ya
The base
object
class has a ToString()
method already
And record
overrides that
And you override... thatConsole.WriteLine
calls ToString()
on what you pass to it, to get what to print.So if you were to override the
ToString
method of another class, it would only work for that classyeah
so its about the placement and what is actually being affected by the override
It's about classes having methods
And records having methods
And structs having methods...
It's how OOP works
yeah
well thanks guys
its almost 3am for me so im gonna stop coding now
but i appreciate the help i have learnt a lot
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.