I have two variants to work with my objects full of data:
let global_obj = {
"id0": { /*big object 0*/},
"id1": { /*big object 1*/},
"id2": { /*big object 2*/}
};
and:
let global_arr = [
{ id: "id0" /*big object 0*/},
{ id: "id1" /*big object 1*/},
{ id: "id2" /*big object 2*/}
];
So I can save my big objects full of data inside of a global array or a global object. Which way is better in terms of performace (looping through, deleting, adding new objects)?
I am going to address specific objects by their id very often, change objects' properties, loop trought them all.
I would use an object in this case as finding an element by id is easier/faster. If index/order of elements is important, object don't help here and you need to use an array.
Basically:
Objects: Keyed collections
Arrays: Ordered collections
But regular objects and arrays are not the only options if the environment supports ES2015. ES2015 has introduces several APIs for working with collections: Map, Set, WeakMap and WeakSet.
As you mentioned that you'll be "addressing specific objects through their id's very often"; using an Object will be a wise choice for you. Since accessing an object's key is done in O(1) as compared to finding the object in an array, which will be O(n), hence Object will be better in performance.
You should do what's more convenient for you, it most likely won't make a difference.
However, generally, if the top level object is small, the array is always faster than a hashtable/object (the size of the inner objects doesn't matter). If the top-level structure is big, then you should consider the big-o complexity for the operations you want to perform on the top-level structure. See http://bigocheatsheet.com/
Related
When using an array constructor and pushing a few values into it as well as adding named values there are some interesting differences.
let arr = []
arr.push('a')
arr.push('b')
arr.push('c')
arr.foo1 = 'bar1'
arr.foo2 = 'bar2'
arr.forEach and for of iterates only over the indexed values, while for in iterates of the indexes/keyed values.
I guess what I'm wondering is why would anyone use this?
One thing that would be cool to have from both objects and array would be a guaranteed order of key-value pairs
(not just [{key:'value'}, {key2: 'value2'] but something where you could use for of on an object where the order would be based on the order in which the keys of the object were set. I know that's not possible but just suggesting something that would be nice to gain between both objects and arrays)
but It seems as though the order of keyed values is not able to be iterated over, so the order is not guaranteed (unless I'm wrong)
Doing this seems like it is a mix between an object and an array, but why would you mix when you can just create an object or array in a common manner?
Arrays are JavaScript objects like any other that you create. (Almost) everything in JavaScript inherits its prototype from Object.
Now the specification of array is such that the indexes are basically just specifically named properties. a[1] and a['1'] are pointing the same property. The only extra thing is that you have to have a length numeric property. In words of ECMAScript language specification, "Array objects are exotic objects that give special treatment to a certain class of property names".
Now, forEach is defined as a function that will only loop through those "special" properties that an Array instance has. It starts with 0 and finishing with length - 1, and it skips undefined values. It doesn't look at other props. So you only get fields in the array.
for of is an iterator - if you have an iterable object, you basically get its iterator function and then loop over values that it gives you. And an array iterable is giving only those indexed property names. You can read a bit more over at MDN.
Once again, an array is object like any other, but we give some of it's properties special meaning, and it inherits some functions from Array prototype that can deal with those properties.
But for in does not care if this object is special or not. It will simply loop over ALL properties of any object you give it, including an array. That's why when you for in loop the object, you're looping the object's properties, and array indexes are included into this.
Note: usage of for ... in ... is not recommended. E.g in a sparse array, (where you set, e.g. a[0] = 1, a[10] = 1, and leave all other indexes undefined), a for in would just log out those two properties.
So if somebody gives you an object that has properties called 0 and 10, would you call it an array? Nope. Another bad thing is that it will also go over the object's prototype and list out the properties of all the objects this array might have inherited from - and you likely do not want that.
Short answer: there is no such thing as a "named array" in JS.
JS's datatype model is based on objects, which are key/value pair containers, and arrays are a special kind of object with additional (native) logic for dealing with numerical keys.
As such, anything you can do to an object, you can do to an array, but you shouldn't: if you need named keys, use an object. If you need numerical keys with derived properties like length and a utility API like push/pop/shift/unshift, forEach, map, etc. use an array.
Also note that the length property says nothing about the actual array footprint in memory: arrays are not like C/Java/etc arrays at all, behaving more like vectors/arraylists instead: they're just JS objects with numerical key/pair bindings, so if you set an array[0] and then you set an array[99], the length will claim "100" and that number will mean nothing at all: your array, in memory, is just an object with a key/value pair keyed on the string 0 and a key/value pair keyed on the string 100.
This quora answer is pretty good further reading, explaining all of this based on the actual ECMAScript spec definitions.
I am reading the book JavaScript: The Good Parts. It is said that
Objects in JavaScript are mutable keyed collections.
What does mutable keyed collection mean?
AS far as I could find on internet, mutable means the vales can be changes. I couldn't find what keyed collection mean.
Objects are a collection of keys with associated values. This could be referred to as a "keyed collection":
var o = {
foo: "bar",
bar: "baz"
}
(Where foo and bar here are keys).
...which can be changed (as you've already said, the "mutable" part):
o.foo = "foobar";
o.foobar = "bar";
The keyed keyword here means that the data is "named", "indexed" or "keyed".
{
key : value,
key2: value2
}
a collection because it contains a collection of data.
It is about the way objects work in Javascript, they behave like C# Dictionaries, for example, or named arrays in PHP. obj.someKey is equivalent to obj['someKey'] and you can always change the values associated with those keys or indeed delete them.
More advanced: the key uniquely identifies the value stored with it and the system is optimized for performance, so you can use this to index information or to get distinct values of a list,etc.
The Confusing discussion
In this question, there is a discussion on the concepts of associated array and object in javaScript which I got a bit confused.
In this example code:
var check = {
pattern : {
name: /^[a-zA-Z-\s]{1,20}$/,
email: /^[a-zA-Z0-9._(-)]+#[a-zA-Z0-9.(-)]+\.[a-zA-Z]{1,4}$/,
pass: /.{6,40}/,
url: /^[(-)\w&:\/\.=\?,#+]{1,}$/,
aml: /<(.+)_([a-z]){1}>$/
}
};
Here is the discussion makes me confused:
#steven.yang the outer object is not an associative array in your sample, but that is what is being asked for
#sissonb what do you mean by 'outer object is not an associative array'? I think associated array is expressed as object in javascript. The difference is in the notation - either through foo.bar or foo[bar]
#steven.yang associated array means key => value. http://en.wikipedia.org/wiki/Associative_array Your inner object has a key of pattern, the object containing this associative array has no key.
My Understanding of Associated Array and Objects in JS
Associated array is defined as key-value pairs which is expressed as the object in JavaScript.
The outer object assigned to check has a key pattern and an value of another object. The inner object has keys of name, email ... and corresponding values of regular expression objects.
Could both objects be counted as associative arrays?
Not really, here's why:
var arr = new Array();
arr["foo"] = 100;
arr["bar"] = 200;
console.log(arr.length); // Prints 0.
Adding elements to an associative array should increase its length (IMO).
It looks and acts (somewhat) like an associative array because of syntactic sugar. What appear to be "array entries", however, are (just) object properties.
If you define "associative array" as a data structure that stores information as a collection of key-value pairs, then yes, JavaScript objects are associative arrays.
However, the phrase "associative array" is not generally used in the context of JavaScript, rather, we say "object". I'd suggest sticking to standard JS terminology to avoid misunderstandings.
Note that JS also has (non-associative) arrays, with elements accessed via numeric indexes. These are also objects and so allow non-numeric key properties, but this is generally considered bad practice.
There are no associative-arrays in JavaScript. Everything is object.
Certainly they are similar but associative-arrays in JavaScript are just objects.
Associative Array
In computer science, an associative array (also called a map or a dictionary) is an abstract data type composed of a collection of (key,value) pairs, such that each possible key appears at most once in the collection.
As far as I know objects in JavaScript match that definition.
Of course there is no unique "Associative Array" object, that's any different then any other normal object. So if you want associative array functionality use a javascript object.
However the following is a common piece of misinformation
There is no associative array in JavaScript
You should simply ignore these people, maybe try to convince them they are wrong.
My response is coming late, but I hope this can help people to understand this difference. I was reading this post and there isn't a satisfactory definition of an associative array.
JavaScript doesn't have Associative Arrays. These are just objects that you can treat as associative arrays for convenience. In objects you store values as named properties, very similar to associative arrays in other programming languages. That's why you can access the properties like an associative array, but with methods associated to objects. You can test creating an object and try all the things you can do with an associative array, but you can't do all the methods of an array.
I have an object that looks something like this.
var obj = {
speed: 10,
volume: 14,
aux_deform: 1.8,
energy: 21.5,
aux_energy: 0.2
}
There will be additional fields/properties added at runtime, so the object can contain any number of properties at any given time. As you can see in my object example, some properties can start with "aux_".
Now, I want to create another object from this one that contains only properties that start with "aux_".
The way I am doing it now is something like this.
var newObj = [];
for(prop in obj)
{
if (prop.startsWith('aux_'))
{
newObj[prop] = obj[prop];
}
}
Now I have a new object and I can do something like:
alert(newObj.aux_energy);
This works ok, but I am wondering if this is the right approach. Is there any easier way, or a more elegant way for what I am trying to achieve? Are there any (security or technical) issues/problems with this way of creating objects?
And the question from the title: is the newly created object actually an associative array with properties as keys (since it's created that way) or is there any difference.
There are no associative arrays in Java Script, there are only JSON objects which can be used in place of associative arrays. What you did here is that you have declared an array called newObj and then added properties to this array. It could lead to unexpected behaviors when trying to use buit in Array methods or when iterating over it. The main difference between JSON objects and arrays is that properties in objects aren't sortable and iterating over them can produce random and unpredictable output.
More appropriate way to write that would be to declare an object newObj = {} and then just copy the properties you need.
One thing to note - if you will have arrays or objects as values for properties you will copy references to these objects. If you'd like to be able to edit these values independently from the original object you'd have to deep copy these values - check this question for how to on that What is the most efficient way to deep clone an object in JavaScript?
Apart from that it's the only way to do that and it's perfectly fine.
I have a js 'associative' array, with
array['serial_number'] = 'value'
serial_number and value are strings.
e.g. array['20910930923'] = '20101102'
I sorted it by value, works fine.
Let's say I get back the object 'sorted';
Now I want to access the first KEY of the 'sorted' array.
How do I do it? I can't think I need an iteration with
for (var i in sorted)
and just stop after ther first one...
thanks
edit: just to clarify, I know that js does not support associative arrays (that's why I put it in high commas in the Title).
2021 Update
Since ES6, properties with string keys are enumerated in insertion order. Here's a nice summary. My original answer from 2010 was correct at the time and is preserved below:
Original answer
JavaScript object properties are specified to have no order, much though many people wish it were different. If you need ordering, abandon any attempt to use an object and use an Array instead, either to store name-value objects:
var nameValues = [
{name: '20910930923', value: '20101102'},
{name: 'foo', value: 'bar'}
];
... or as an ordered list of property names to use with your existing object:
var obj = {
'20910930923': '20101102',
'foo': 'bar'
};
var orderedPropertyNames = ['20910930923', 'foo'];
Try this:
// Some assoc list
var offers = {'x':{..some object...}, 'jjj':{...some other object ...}};
// First element (see attribution below)
return offers[Object.keys(offers)[0]];
// Last element (thanks to discussion on finding last element in associative array :)
return offers[Object.keys(offers)[Object.keys(offers).length - 1]];
Actually JavaScript doesn't support associative arrays, so you can't loop through it in an implied order (e.g. you can't access it via the indexer property array[0] won't access the first element in your object). The syntax is what makes it look like it does, but in reality it doesn't. So you have no "Order" to your objects.
http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
Javascript does not have, and does not
support Associative Arrays. However…
All arrays in Javascript are objects
and Javascript's object syntax gives a
basic emulation of an associative
Array. For this reason the example
code above will actually work. Be
warned that this is not a real array
and it has real pitfals if you try to
use it. The 'person' element in the
example becomes part of the Array
object's properties and methods, just
like .length, .sort(), .splice(), and
all the other built-in properties and
methods.
Just thinking off the top of my head, but could you have another array with the key value pairs swapped?
So the answer would be arrayKeyValueReversed['20101102'] = '20910930923';
When you sort the array, use the first item (array[0]) as the key to get the value in the arrayKeyValueReversed.