Populating a Dictionary from a CSV File with Words Separated by Semicolons
Hi, I want to create a small console app for learning new vocabulary, and I need to populate a dictionary (source language: target language) from a CSV file that contains vocabulary in this format: english;german\n. How could I populate a dictionary?
104 Replies
When you say dictionary, do you mean an actual
Dictionary<string, string>
?
with what language being key and what being value, in that case?
The classic "ask a question and immediately go offline so now followup questions can be asked" tactic.I want to use English word as key and German as value
Okay. Do you want to use this as a learning experience or just have the answer?
I want to learn
Okay great. So, what would be a logical place to start?
Use a for loop with Split method?
To iterate thru each line and populate arrays
something along those lines, sure
but we can use
LINQ
and functional coding to do thisSounds interesting
the data from our file can be either a raw string or a
string[]
, depending on how you read itOkay, I want to treat it as a string
Normally you read the data line by line if not using CSV reader or something..
okay, so we read the file into a single string.
next, we do need to split it by lines, since each line contains one key-value pair
how would you do that?
Pobiega, Is it good idea to use a single dictionary for displaying English words and checking user input with German words?
Split it by \n char and put it in array?
I mean, it could cause problems with case sensitivty and multi-word words, but other than that, should be fine?
Would it be hard to deal with both problems?
okay, lets go with that
I added some options to split to clean up data. not strictly needed, but can help if the csv files contains a trailing blank line, or whitespace
Now the hardest part, populating two different arrays
well, if we wanna do linq, we dont do that 🙂
We're gonna use something called
.Select
this lets us transform our sequence (currently an array of strings) into a new sequenceWhich condition will we put in select method?
no condition. Select doesnt take a condition, it takes a
Func<TSource,TResult>
we can start with this
a sample line might look like..
thank you;danke
what would be a good transformation to apply here?Wow
Separate string by semicolon?
yes!
Will it give us a list back?
okay,
result
is now a sequence of string[]
s
no, not unless we call .ToList
to make it a list
but we dont want to do that
we can still work with it as a sequence (IEnumerable
)So it’s a sequence of all words?
well, its a sequence of string arrays, where the first item in each array is the english word, and the second is the german word
I dont think we can do any more meaningful transformations at this point, so we should just "finish" the sequence by collecting it into its final shape: a dictionary
I think now we need to put first object to sequence to english words array and second to German array
How could we do that?
Well, LINQ has a lovely
.ToDictionary
method
I suggest we use that 😄Nice
it has a few different overloads, but the one we probably want is...
Side question: how does sequence look like?
ToDictionary(keySelector, valueSelector)
wdym?And what is it?(in simple language)
the type of a "sequence" in C# is
IEnumerable<T>
you can see here from my Rider window
Okay
Could we apply it to our linq query?
we certainly can
What do you suggest we use for keySelector and valueSelector?
But is it good practice to put so much of methods to one line of code?
they should be
Func<TSource, TResult>
s
sure, why not?
we are breaking it up so its readable and lovelyPobiega, I need to go to important meeting now. Could I hit you up in DM after I’ll comeback?
I'd argue this is a lot more readable than the nested loops that would do this without linq
no, but you can ping me here
Okay, thanks
@Pobiega, I’m back
Pobiega
What do you suggest we use for keySelector and valueSelector?
Quoted by
<@105026391237480448> from #Populating a Dictionary from a CSV File with Words Separated by Semicolons (click here)
React with ❌ to remove this embed.
What should I pass to ToDictionary method?
Two funcs
One that selects the key, one that selects the value
Could I use Split method two times?
@Pobiega
You can
.Select()
to split each element first, then .ToDictionary()
the results of that splitwe've already done that
we're at
the only thing left is the
ToDictionary
call with the two selectors
so tell me @danilhieshka how would we get the key from our string[]
thats currently in the sequenceI don’t know
How could I do that?
How would we get the first item from an array?
Should I use index 0 and 1?
Yep
ToDictionary(0,1)?
No
.ToDictionary()
takes two lambdas, as Poibiega already said
The key selector, and the value selectorAngius
REPL Result: Success
Result: Dictionary<int, string>
Compile: 466.067ms | Execution: 68.529ms | React with ❌ to remove this embed.
For example
the selectors are lambdas (anonymous functions) that take the current object in the sequence in, and produce whatever value you want as your key/value out
so write a function in the format of
x => x
that takes a string[]
in, and produces the key you want for that word combo
then do the same for the valueToDictionary(x => vocabulary.english, x => vocabulary.german)?
well yes, but
vocabulary
doesnt exist
reasonbly, you'd derive the values from x
somehow
and remember, x
is the string[]
that contains a single split word-combo
ie, english and germanSimply x.0, x.1?
Is that how you get items from an array?
x is the array.
Ah, x[0], x[1]
yes.
Yep
Thank you guys!!
Special thanks to Pobiega, your explanation was great
and assuming basic C# knowledge, and understanding lambdas... I think this is so much more readable and understandable compared to doing it with loops
LINQ is very very common in modern C#
I think you’re right
What should I learn first, LINQ or basics of OOP?
oop
the basics of OOP are almost mandatory to understand C#, imho
we write classes and methods all the time, so that just needs to be solid
Okay
I kind understand how to create classes and use methods, but in very simple level
thats fine
you need to start somewhere 😄
I also wanted to ask, for the main part of the application, where the user would be asked to input vocabulary, should I use some kind of loop or another method?
hm
I thought you said it would be read from file?
that makes more sense to me
as a user, manually entering the vocabulary each time I want to practice seems silly 😄
Yep, but then user would be asked to translate vocabulary from English to German
oh like, it would pick a random word and say "what is this in german?"
Yes
yeah, that would be with a loop
And also, how to shuffle words?
Great, thanks
easiest way is probably to just make a copy of the dictionary key list, and sort it by random
since you dont need any advanced type of shuffling
Could I use LINQ for sorting?
yes
Which method will be appropriate in my case?
.OrderBy
Like that ?
that seems expensive
and also, frankly, not needed
its probably simpler to just copy the keys, and generate a random index as needed when asked
(no spoilers :D)
That looks nice
How could I implement it ?
Random
classRandom.Shared.Next(max)
generates a number between 0 and max-1
perfect for indexing a list/array of size max
the code inside that loop is very simple, it checks for an early exit (pressing enter without typing a guess in my case), otherwise it just takes your guess, looks up the correct answer and then says if you got it right or not
oh, and ofc it gets a random english word from the list of keys (english
) as the very first thingShould I use it inside .OrderBy method ?
You can get the keys of the dictionary as a list
Then get a random key
@Pobiega Hi. Could you explain me please in details, how does this code works and why did you used Select method? I want to understand this code deeply
I already have
Pobiega
this lets us transform our sequence (currently an array of strings) into a new sequence
Quoted by
<@105026391237480448> from #Populating a Dictionary from a CSV File with Words Separated by Semicolons (click here)
React with ❌ to remove this embed.
@Pobiega Hi, shoudl I use a for loop to shuffle my vocab dictionary?
Do you want to shuffle it, or just get a random item?
I want to shuffle it
Fischer-Yates algorithm is usually the golden standard
But there's also
Random.GetItems()
IIRC
And Random.Shuffle()
that does an in-place shufflingyou dont shuffle it
you just get a random index
Okay, but what if create a copy of a dictionary, shuffle it and then use it throught app;ication?
Pobiega, I think you've already told me that I could use OrderBy method for that
How could I do that exactly?
Surely you can figure this one out on your own?
Sorry for asking too much
I've got it working