1

I have a simple string and i split it into an array:

var alphabet = "a,b,c,d,e";
var letters = alphabet.split(",");

var dict = [];
for ( var i = 0; i < letters.length; i++ ) {
    dict[ letters[i] ] = true;
}

What stumps me is that when i do a

console.log(dict[letters[0]] +"|"+ dict["a"]);

I get

//true|undefined

I dont understand the difference between letters[0] and "a". And i'm absolutely sure that letters[0] and "a" are both type of string.

EDIT: I just tried changing variable "dict" from the square brackets to the curly ones but it still gives me undefined.

EDIT 2: The below code is what im working with. "dictionary.txt" is a text file containing some 90k words separated by "\n". In this text file, the letter "a" is on the first line.

$.get( "tiles/dictionary.txt", function( txt ) {
// Get an array of all the words
var words = txt.split( "\n" );
// And add them as properties to the dictionary lookup
// This will allow for fast lookups later
for ( var i = 0; i < words.length; i++ ) {
    dict[ words[i] ] = true;
}
console.log(dict[words[0]]+"|"+dict["a"]);
});

Maybe i should have just started out with this, instead of trying to make a simplified version of it.

10
  • My local Node.JS and the JSFiddle created by @Ajwhiteway both work as written, so it's not the code. What implementation of JS are you using? Commented Dec 10, 2015 at 19:53
  • @MarkReed hi Mark please see my EDIT 2, thank you. I am not sure what JS im using, but im on Netbeans 8.0.2 Commented Dec 10, 2015 at 20:05
  • So none of the lines of the file is just a. Perhaps there is whitespace besides the newline? Commented Dec 10, 2015 at 20:09
  • 1
    add 1 line to your test code both version console.log(words[0] == "a") Commented Dec 10, 2015 at 20:12
  • @HopefullyHelpful huh interesting, I didnt think to test that. It turns out to be false. Commented Dec 10, 2015 at 20:15

4 Answers 4

5

The problem is that your text file has carriage returns. Splitting on newline ("\n") doesn't remove the carriage returns, so the first element of the array is not "a" but "a\r". If you modify your code to the following, it should work, as it does in this fiddle:

$.get("https://dl.dropboxusercontent.com/u/16966255/dictionary.txt",
      function(txt) {
        var words = txt.split("\r\n");
        var dict = {};
        for (var i = 0; i < words.length; i++) {
          dict[ words[i] ] = true;
        }
        alert(dict[words[0]]+"|"+dict["a"]);
      });

Instead of requiring the file to contain carriage returns, you could split with a regular expression that matches whether it does or not:

var words = txt.split(/\r?\n/);

But if you plan on using a much larger file, note that splitting with a regex is noticeably less efficient than splitting with a constant string.

Also, while I have changed the initialization of dict from [] to the more standard {}, that was not the problem; an Array is just a particular type of Object, and every Object in Javascript is really an associative array.

Sign up to request clarification or add additional context in comments.

6 Comments

"every Object in Javascript is really an associative array" I wouldn't say that. Objects are more like dictionaries or maps. "Associative array" implies a certain order of the elements, which is not the case for object properties. Actually, any comparison of objects to another data structure is probably wrong.
@Mark-reed You're goddamn right. IF you type typeof [] you will see "object".
@FelixKling No, "associative array" does not imply ordering of elements; it is synonymous with "dictionary" or "map" in those senses. PHP is probably the best-known implementation that actually calls them "associative arrays", and its are ordered, but that is not at all implied by the name.
Fair enough... I won't venture deeper because it only gets more confusion (en.wikipedia.org/wiki/Array_data_structure vs en.wikipedia.org/wiki/Array_data_type, etc)
Ahh, you have satisfied my curiosity. This is the correct answer. +1
|
3

Your dict var needs to be an object, not an array. In JavaScript, associative arrays are JSON objects.

var dict = {}; // Curly braces, not square brackets.

for ( var i = 0; i < letters.length; i++ ) {
    dict[ letters[i] ] = true;
}

console.log(dict[letters[0]] +"|"+ dict["a"]);

You will get

// true|true

3 Comments

It's more conventional to use the object literal syntax {}, but it absolutely still works if you use the array literal syntax [] instead. Try before dismissing..
@MarkReed while it technically 'works', it is just adding keys to the array object, not adding array items. The length is 0, and iterating on it will cause some unexpected results. It should be an object literal.
It's not best-practice, but it doesn't explain the problem seen in the question.
2

I ran your code as it on JSFiddle and it logged true|true. You could try changing

dict = [];

to

dict = {};

on your local implementation to see if it corrects your problem.

Comments

-2

Javascript doesn't support associative arrays. If you declare it with [], all indexes must be numbers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.