I'm new to javascript and I cannot find answer about some issues, one is the following:
Why in js would be useful an hash table data structure when we can use objects as associative arrays that is simple to use and have a very good performance?
why in js would be useful an hash table data structure when we can use
objects as associative arrays that is simple to use and have a very
good performance?
The only reason I can imaging to implement an hash table data structure is if you want to preserve the ordering of the elements. The for…in loop for objects doesn't guarantee to you in which order the properties ("keys") are returned, even if commonly you can obtain them in chronological order (last added, last returned). But it's not guarantee. For instance, old version of Opera returned the properties in an apparently random order. So, if you need an "ordered" hash table, you need to implement it by yourself.
A javascript hashtable and javascript associative array (and javascript objects) are all the same thing in the underline implementation. These are just different syntax.
So :
var a = {};
a.id = "aa";
is same as:
var a = new Object();
a.id = "aa";
Which is is same as:
var a = {};
a["id"] = "aa";
Associative arrays and hashtables are the same.
These expressions usually means the same too: dictionary, associative array, hashmap, map, hashtable and... the list goes on.
There is a difference between simple ARRAY and HASHTABLE though.
If you want to search an item in an array, the more items you have inside it, the longer will the search takes.
For example searching an item in an array with 10000 elements could takes 100 times longer than in an array with 100 elements.
With hashtables, no matter how many elements you have, the performance remains the same. (Be it 100 elements or even 99999999 elements...)
Related
I learn JavaScript through the "JavaScript & jQuery" book by John Duckett (Russian translate).
Author writes two code examples of array item getting:
var colors = ["white", "black","custom"];
var el = document.getElementById('colors');
el.textContent = colors[0];
and
var colors = new Array("white", "black","custom");
var el = document.getElementById('colors');
el.innerHTML = colors.item(0);
In the article he wrotes that for getting of array item can be used item() method. But in the code sources he uses colors[0] instead of colors.item(0) in the second variant.
I see that colors.item(0) doesn't work. Is it wrong info?
JavaScript arrays are specialised objects, which have a particular behaviour and a particular set of methods. .item() is not one of them.
There are many other JavaScript objects which also contain a collection of values. Some of these objects include an .item() method.
The thing is, even though these objects may have some similarity with arrays in that they contain a collection of values, they’re not the same. Arrays, have some features, and these other objects have some others.
To learn more about what JavaScript arrays do have, you can look at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
In principal, it would be possible to add an .item() method to arrays by adding to the Array prototype. However, it is certainly not a natural part of JavaScript arrays.
Edit
One of the important properties of the array is in how it is accessed: you can read, replace or create an item using the square brackets ([]). Non-array collections don’t have this feature, so the items need to be accessed with a dedicated method.
Another important property is that the .length property is automatically updated.
Yes, it looks like a mistake in the book. The Array class doesn't have an item method. colors[i] should be used to get an element at a specified index.
This is more a general question about the inner workings of the language. I was wondering how javascript gets the value of an index. For example when you write array[index] does it loop through the array till it finds it? or by some other means? the reason I ask is because I have written some code where I am looping through arrays to match values and find points on a grid, I am wondering if performance would be increased by creating and array like array[gridX][gridY] or if it will make a difference. what I am doing now is going through a flat array of objects with gridpoints as properties like this:
var array = [{x:1,y:3}];
then looping through and using those coordinates within the object properties to identify and use the values contained in the object.
my thought is that by implementing a multidimensional grid it would access them more directly as can specify a gridpoint by saying array[1][3] instead of looping through and doing:
for ( var a = 0; a < array.length; a += 1 ){
if( array[a].x === 1 && array[a].y === 3 ){
return array[a];
}
}
or something of the like.
any insight would be appreciated, thanks!
For example when you write array[index] does it loop through the array till it finds it? or by some other means?
This is implementation defined. Javascript can have both numeric and string keys and the very first Javascript implementations did do this slow looping to access things.
However, nowadays most browsers are more efficient and store arrays in two parts, a packed array for numeric indexes and a hash table for the rest. This means that accessing a numeric index (for dense arrays without holes) is O(1) and accessing string keys and sparse arrays is done via hash tables.
I am wondering if performance would be increased by creating and array like array[gridX][gridY] or if it will make a difference. what I am doing now is going through a flat array of objects with gridpoints as properties like this array[{x:1,y:3}]
Go with the 2 dimension array. Its a much simpler solution and is most likely going to be efficient enough for you.
Another reason to do this is that when you use an object as an array index what actually happens is that the object is converted to a string and then that string is used as a hash table key. So array[{x:1,y:3}] is actually array["[object Object]"]. If you really wanted, you could override the toString method so not all grid points serialize to the same value, but I don't think its worth the trouble.
Whether it's an array or an object, the underlying structure in any modern javascript engine is a hashtable. Need to prove it? Allocate an array of 1000000000 elements and notice the speed and lack of memory growth. Javascript arrays are a special case of Object that provides a length method and restricts the keys to integers, but it's sparse.
So, you are really chaining hashtables together. When you nest tables, as in a[x][y], you creating multiple hashtables, and it will require multiple visits to resolve an object.
But which is faster? Here is a jsperf testing the speed of allocation and access, respectively:
http://jsperf.com/hash-tables-2d-versus-1d
http://jsperf.com/hash-tables-2d-versus-1d/2
On my machines, the nested approach is faster.
Intuition is no match for the profiler.
Update: It was pointed out that in some limited instances, arrays really are arrays underneath. But since arrays are specialized objects, you'll find that in these same instances, objects are implemented as arrays as well (i.e., {0:'hello', 1:'world'} is internally implemented as an array. But this shouldn't frighten you from using arrays with trillions of elements, because that special case will be discarded once it no longer makes sense.
To answer your initial question, in JavaScript, arrays are nothing more than a specialized type of object. If you set up an new Array like this:
var someArray = new Array(1, 2, 3);
You end up with an Array object with a structure that looks more-or-less, like this (Note: this is strictly in regards to the data that it is storing . . . there is a LOT more to an Array object):
someArray = {
0: 1,
1: 2,
2: 3
}
What the Array object does add to the equation, though, is built in operations that allow you to interact with it in the [1, 2, 3] concept that you are used to. push() for example, will use the array's length property to figure out where the next value should be added, creates the value in that position, and increments the length property.
However (getting back to the original question), there is nothing in the array structure that is any different when it comes to accessing the values that it stores than any other property. There is no inherent looping or anything like that . . . accessing someArray[0] is essentially the same as accessing someArray.length.
In fact, the only reason that you have to access standard array values using the someArray[N] format is that, the stored array values are number-indexed, and you cannot directly access object properties that begin with a number using the "dot" technique (i.e., someArray.0 is invalid, someArray[0] is not).
Now, admittedly, that is a pretty simplistic view of the Array object in JavaScript, but, for the purposes of your question, it should be enough. If you want to know more about the inner workings, there is TONS of information to be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
single dimension hash table with direct access:
var array = {
x1y3: 999,
x10y100: 0
};
function getValue(x, y) {
return array['x' + x + 'y' + y];
}
i hope my question isn't that dumb. But i've wondered how arrays actually work in javascript. Espacially getting an element by index.
Let's assume i have an array called myFirstArray with the elements [1,2,3,4].
When i type myFirstArray[3], how does it work to get the fourth element from that array?
Does it loop through? So everytime i want the last element of an array it is looping through the whole array?
Same goes with adding an element to an Array. Do it loop always through the array do find the last element in the Array?
I'm asking because i implemented a linkedList into Javascript and im wondering if it is more efficient than an normal array.
The implementation of arrays in Javascript is a little different from how it's done in most other languages.
An array isn't just a list of items, instead it is a associative array. Items aren't stored after each other, instead they are stored as discrete key-value pairs. If you for example put values at index 3 and 5, the array doesn't contain undefined items to fill up the gaps, it just has the values that are set.
With code like this:
var a = [];
a[3] = 1;
a[5] = 2;
The data that is stored in the array doesn't look like this:
[ undefined, undefined, undefined, 1, undefined, 2 ]
Rather it looks like this:
{
"3": 1,
"5": 2,
"length": 6
}
The items in the array is stored as properties in the array object, it's just that the array handles properties with a numeric key in a special way, i.e. adjusting the length property if needed.
The implementation of the key-value collection is done using a hash table (or perhaps something even more efficient, depending on the Javascript engine), so accessing an item is close to an O(1) operation, i.e. it doesn't loop through all properties until it finds the right one.
How array access is realized is up to the JavaScript engine itself and may hence differ from engine to engine.
I would guess though that arrays are still blocks of memory in most engines. If you access an element, the array is not circled through. Rather the memory address for that specific element is calculated (memory_offset_of_the_first_element + size_of_element * desired_index) and then the element can be gathered from there. Insertions and deletions are a more complex and expensive. In worst case the whole array needs to be copied and adjusted.
Lamar provided a good overview in When to use a linked list over an array/array list?.
In Javascript there are standard built-in objects and one of those objects is Array. Array is high-level global object and is used as a constructor for arrays.
Array elements are object properties that can be accessed through bracket notation. In other languages you would call Javascript arrays as sparse arrays (ex: Wolfram).
Is it good practice to create a JavaScript array inside another array?
Example: I would create an array, "array1", which would contain objects of "array2" and "array3".
Example Code:
var array1 = [];
var array2 = []
array1.push(array2);
The reason I ask this question, is that with a multidimensional array, it seems hard to get the length of all dimensions, however, with this "inner-array," you could get the dimensions quite easily:
array1[0].length
Note that generally it is called "jagged array" (array of arrays) which is not necessary represent rectangular matrix (usually multidimensional arrays that have same number of elements on each level).
JavaScript does not support what usually considered "multidimensional arrays" unlike some other languages where you can do something like matrix = new int[10,20]. So this is the only way to create "multidimensional array" in JavaScript. This post How to initialize a jagged array in JavaScript? may give you other way to initialize the array.
If using it for matrix manipulation code be careful when adding inner arrays: usually code would expect rectangular shape(like nested for loops) and may fail if some inner arrays have wrong dimensions.
Is it good practice to create a JavaScript array inside another array?
The elements contained in an array can be everything, even other arrays. So there's nothing bad in doing that.
The reason I ask this question, is that with a multidimensional array,
it seems hard to get the length of all dimensions, however, with this
"inner-array," you could get the dimensions quite easily
Your "inner-array" is, in fact, a multidimensional array.
I'm building an Entity System for a game, and basically I'm not sure whether I should use simple objects (dictionaries) or arrays to to store the entities/components by their id.
My biggest issue is that I didn't want a dynamic entity id. If the id was just a string (using the dictionary to store entities), then it would always be valid and I could use storage[id] to get to that entity.
If I used arrays, I thought, the id's of entities, which would represent an index in the storage array, would change. Consider this array of entities:
[
Entity,
Entity, //This one is being removed.
Entity
];
If I was to remove the second entity in that array, I thought that the id required to access the third array would have to change to the id (index) of the (now removed) second entity. That's because I thought about deleting in terms of splice()ing.
But, I could use the delete expression to turn the element (an entity) into an undefined! And, if it's true that arrays in Javascript are actually just objects, and objects logically have infinitely many undefined values, does that mean that undefined values inside arrays don't use up memory?
Initially, I though that arrays were implemented in a way that they were aligned in memory, and that an index was just an offset from the first element, and by this logic I thought that undefined values would use at least the memory of a pointer (because I, actually, thought that pointers to elements are aligned, not elements themselves).
So, if I stored 10k+ entities in this array, and deleteed half of them, would the 5k undefined's use any memory at all?
Also, when I do a for entity in array loop, would these undefined elements be passed?
Also, where can I find resources to see how arrays are actually supposed to be implemented in Javascript? All I can find are general explanations of arrays and tutorials on how to use them, but I want to find out all about these little quirks that can prove important in certain situations. Something like a "Javascript quirks" site would be great.
Arrays are not just objects. In particular the length property is very magic.
Of course, a JavaScript engine is allowed to represent the array internally in any way it chooses, as long as the external API remains the same. For instance, if you set randomly separated values then they may be stored as a hash, but if you set consecutive values then they may be optimised into an array.
for ... in does not enumerate properties that are not set. This includes an array literal that skips values e.g. [true, , false], which will only enumerate indices 0 and 2.