- Home /
Searching through a text file with Unity?
I'm teaching myself Unity over the summer as a side project, and decided a good way to start out was porting a word puzzle game I made previously over to the Unity engine. This has been successful so far, but I've run into a block I can't find a way around, which is checking my dictionary to check if the words the player inputs are actually valid.
My dictionary is in simple .txt format, with each word listed in the following format:
aals
aardvark
aardwolf
aargh
The game was originally built in Python, where I used ReadLines() to load the dictionary into an array (set) so I could loop through it when searching for words. I can't find any comparable way to do that with Unity however; text input/output functionality seems to be lacking with UnityScript.
Anyone know how I could check if a string variable exists within the dictionary?
Answer by whydoidoit · Jun 16, 2012 at 12:23 AM
Create your file as a .txt and put it in a Resources folder.
import System.Collections.Generic;
import System.Linq;
...
var lex : Dictionary.<String, String>;
function Awake() {
var textAsset = Resources.Load("YourFileNameWithoutTheDotTxt", typeof(TextAsset)) as TextAsset;
lex = textAsset.text.Split("\n"[0]).ToDictionary(function(w){return w;});
}
function Checkword(word : String) {
return lex.ContainsKey(word);
}
Note Lists (as well as Arrays) are slow when searching entries, it's O(n). Using a binary search for alphabetized sorted Lists is still O(log n).
Yeah I know I'd never use one in anger :) Shouldn't have been so lazy.
Ah, nice, didn't know you could parse the file and fill the Dictionary in one line :D
Declare your dictionary as:
Dictionary<String,String> wordList = new Dictionary<String,String>();
, and then try something like:
wordList = textAsset.text.Split(new Char[] {'\n'}).ToDictionary(w => w);
Not absolutely sure about the syntax, though, never really used this.
Answer by Wolfram · Jun 16, 2012 at 12:42 AM
The by far fastest method to test whether a string is within an arbitrary large array/set/list of strings is by using a Hashtable, it will find objects in O(1) time.
Instead of storing your strings in a regular array or list, use:
myHashtable.Add(myWord,myWord);
or:
myHashTable[myWord]=myWord;
(the second "myWord" entry doesn't really matter, as long as it's non-null. You could also use it to store additional info)
To test whether a word exists use:
myHashtable.Contains(searchWord);
To retrieve the second parameter mentioned above use:
secondParameter=myHashtable[myWord];
Note you can also store different objects instead of just strings, even GameObject references and so on.
Damn my laziness of not using a Dictionary has been found out!!!
Answer by Kurius · Jul 24, 2018 at 09:45 PM
I had to combine some ideas from a couple users here in order to arrive at this correct line...
lex = textAsset.text.Split("\n"[0]).ToDictionary(w => w);
User whydoidoit didn't have the w => w
User Wolfram didn't have the "\n"[0]
Hope this helps others :-)
Answer by unity_Jbg_1vKSGY4bdQ · Apr 03, 2021 at 06:56 PM
For those struggling with why ContainsKey() does not find your strings a match, it's because Split() adds an empty character to the end of your strings/keys. To solve this issue, simply add a Remove() to your code:
lex = textAsset.text.Split("\n"[0]).ToDictionary(w => w.Remove(w.Length - 1);
Also, if you want to read your .txt file from a path, you may want to put the file into the StreamingAssets folder. See details here
Your answer
Follow this Question
Related Questions
High score local [Android] 1 Answer
How to managing text file 1 Answer
Reading from a file not working on Android 0 Answers
dictionary, random element (js) 1 Answer