understanding nested arrays in Javascript - javascript

I want to create a nested array in Javascript but can't do the thing what I want, I don't know if it is even possible. Here is an example of what kind of array I want to create:
var array = ['id1', 'id2', 'id3', 'id4'];
Then I want to add new array for each id such way that id values stayed the same. Why? because I want to use indexOf method to find out the element index of main array with sub array id. Something like this:
array[0]['par1'] should return the value of parameter1
array[0]['par2'] should return the value of parameter2
...
array[0] should return "id1" because
alert(array.indexOf("id1")) must return 0 ;
If there is some way of doing it, that would be great to know, but if it is not than I think I will use 2 arrays, one will hold sub arrays and another the ids
sorry for my bad English, I tried my best to explain my needs.

Maybe you want to do
array[0] = {par1: 'somevalue', par2: someother};
array[1] = {par1: 'anotehrone', par2: stillanother};
This sets as elements of you array javascript objects, here used as associative arrays. They enable you to set or get elements by key :
array[0]['par1'] = 'new value'; // write
var newval = array[0]['par1']; // read
But if you also want to have array[0] returning something that's not a generic object but a string... then you probably don't want javascript. This language just doesn't work like that.

Related

javascript adding a property to all objects in an array

I have an array of objects that is fed by an external API e.g
[{prop: val1}, {prop: val2}, {prop: val3}....]
I have to feed this object(my code) to a third-party library which expects the name of the property on the object to be 'xyz' instead of 'prop'.
What is the most efficient way (memory wise and faster) basically avoiding both:
1. iterating over the array
2. adding 'xyz' property to all objects in the array
to achieve this?
I am thinking along the lines of adding a getter for xyz to all objects that return the 'prop' value, but that does not save the looping.
Adding the getting on the prototype level (Object.property) seems like a bad idea at this point.
Edit: I am not looking for different ways to loop through arrays in javascript like forEach or map. I have a very specific ask, and i am interested in exploring if it is at all possible to simply have a property proxy for 'xyz'.
Array map is used to cycle trough an array.
myArray.map(function(obj){
obj.xyz = 'yourvalue';
return obj;
}
You can use Array.map to create a new from the array you received by the API.
var newArray = oldArray.map(function(obj){
return {newKey : obj.prop};
});
In this example, newKey will be the key property you want, instead of 'prop', and it's assigned the old 'prop' value

Getting Key name of an Object item

Before marking this as a duplicate, i've spent a lot of time looking through similar question and most of the answers did not solves my situation.
i have a huge list of items as objects by IDs. like this, in a Map (userDB)
{
"15321":{name:"name1",status:"status1"},modules:{...},
"15322":{name:"name1",status:"status1"},modules:{...},
"15323":{name:"name1",status:"status1"},modules:{...}
}
now i need to make an operation in which i need all these IDs, in that case, the key names of every item on it. i need to get these "15321","15322" etc.
more specifically i wanted something that i could fetch in something like
userDB.forEach( u => {
//something here to get u's key
})
i've tried Object.keys(), but it will return a list of IDs as an object
{"15321","15322"...} in which i still cant grab the ID string
i've tried for (i in Object.keys(userDB)) too, no successs
i double-checked for silly syntax errors and everything of the sort.
Things that will be nice to get in mind to answer this:
dont try to show me a new way of storing stuff, it is already stored so you will not be of help
the result SHOULD be the ID as a string, the name of the key.
dont ask "why i want to make this". just answer and dont try to change this scenario. because this is what i've seen in most of the other similar questions and it is what makes me walk in circles every time.
TL;DR. i just want to get the parent key names of the object im currently processing
Object.keys(obj) will return an array.
But in your data there is another key modules except IDs.
So you can use this :
var keys = Object.keys(data);
keys.pop();
console.log(keys); // ["15321", "15322", "15323" ...]
You might be confused. Object.keys(obj) returns an array. In your case it looks like this: ["15321", "15322", "15323"]. You could iterate through that array like so and you'll have both the key and the object and you'll be able to do with them whatever you want. Below is a for loop that attaches the key to the object as a key named 'key'.
var keys = Object.keys(myObject);
for(var i = 0; i < keys.length; i++){
var key = keys[i]; // this is your key
var obj = myObject[key]; // this is the key's value
obj.key = key;
}
EDIT
In javascript an Array is also an object, but the 'keys' so to speak are usually numbers instead of strings. So an array that looks like this:
["Hello", "there"] is essentially represented like this: { 0 : "Hello", 1 : "there" }
When using for-in on an array, it'll loop through the keys, but those keys will be 0, 1, 2... instead of the items themselves.

Javascript Array Key Lookup

I'm sorry if this has been asked before, it's something that's difficult to search for...
I want to use a javascript Array to hold objects, with the key as the ID
for example, let's say I had a bunch of people who had different IDs
var people = new Array();
var person = {property: value}; // this is person ID 4
var people[4] = person;
I want to be able to then reference that user by saying, people[ID].propery
The problem is that the output of this array now would be;
null,null,null,null,object
Because it's expecting the keys to be 0,1,2,3,4
Am I being stupid or something? :-) We can do it for strings right, so why not non-sequential numbers?
What I'm trying to avoid is having to loop over every single object in the array every time I want to access a particular person inside it, therefore I figured that using the ID number as the key would work
Thanks guys! :-)
Use a dictionary object
var people = {};
people[4] = 'me';
I'd suggest you use collections. A collection is an array of objects. You can then pass properties on each person. You can filter your collection by any property. So close to what you're doing, but instead of relaying on the index, pass the id for each person.
var people = []; // a collection
var person = {
id: 4,
name: 'John'
};
people.push(person);
// Filtering:
// By id
var john = people.filter(function(person) {
return person.id == 4;
});
// By name
var john = people.filter(function(person) {
return person.name == 'John';
});
You can abstract those loops above to re-use them. Also make sure your id's are unique. If data is coming from the DB it should be OK, otherwise I'd keep track of them somewhere.
The advantage of collections, as opposed to a plain object with keys is that you can sort and filter, while an object, where the order of properties is not guaranteed, you can't do it as simple.
Note that filter only works on "modern browsers", so IE9+, but there are polyfills for older browsers.
when we use a string as key, like this:
var people = {}; //this is an object
people[name] = 'toto';
we are adding new property to this object, because each object in javascript can be seen as a hashtable.
If you use an array, it's still an object, you can add properties to it using string as key. But if you do something like people[4] = 'toto';, you are adding a string to the array, the length of the array will then become 5. Of course the number 4 will still be a property of this array object.

How do I access the first key of an ‘associative’ array in JavaScript?

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.

In JavaScript, how do I access an object inherited from Array with the [] operator?

I have a situation, where I need to create a new JavaScript object that is inherited from Array. I am using the following code:
// Create constructor function.
var SpecialArray = function () {};
// Create intermediate function to create closure upon Array's prototype.
// This prevents littering of native Array's prototype.
var ISpecialArray = function () {};
ISpecialArray.prototype = Array.prototype;
SpecialArray.prototype = new ISpecialArray();
SpecialArray.prototype.constructor = SpecialArray;
// Use Array's push() method to add two elements to the prototype itself.
SpecialArray.prototype.push('pushed proto 0', 'pushed proto 1');
// Use [] operator to add item to 4th position
SpecialArray.prototype[4] = 'direct [] proto to 4';
// Create new instance of Special Array
var x = new SpecialArray();
// Directly add items to this new instance.
x.push('pushed directly on X');
x[9] = 'direct [] to 9'
console.log(x, 'length: ' + x.length);
Quite interestingly, the [] operation seem to be useless and the console output is:
["pushed proto 0", "pushed proto 1", "pushed directly on X"] length: 3
What am I missing here?
It is not possible to subclass the Array class and use t this way.
The best solution for you is to extend just the array class and use it as it is.
There are two other options that I do not like but they exist
http://ajaxian.com/archives/another-trick-to-allow-array-subclasses
http://dean.edwards.name/weblog/2006/11/hooray/
This is one of those that always trips people up. The length property only applies to the ordered elements. You can't extend an array then insert an arbitrary non-sequitous key and expect it to work. This is because the relationship between the length property and the array contents is broken once you extend the array. Pointy's link above does a very good job of explaining this in more detail.
To prove this add this to the end of your example:
console.log(x[4]);
As you can see your entry is present and correct, it's just not part of the ordered array.
Like everything else in javascript the Array object is just a Associative Array with string keys. Non numerical, non sequitous keys are hidden to fool you into thinking it's a 'proper' numerically indexed array.
This strange mixed design of the Array object does mean you can do some strange and wonderful things like storing ordered and unordered information in the same object. I'm not saying this is a good idea, I'm just saying it's possible.
As you will have noticed by now when iterating structures like this the non sequitous keys don't appear which makes sense for the general use case of arrays for ordered information. It's less useful, or in fact useless when you want to get keyed info. I would venture that if ordering is unimportant you should use an object not an array. If you need both ordered and unordered store an array as a property in an object.
The best way I have found to create a child prototype of an "Array" is to not make a child prototype of "Array" but rather create a child of an "Array-Like" prototype. There are many prototypes floating around that attempt to mimic the properties of an "Array" while still being able to "inherit" from it, the best one I've found is Collection because it preserves the ability to use brackets []. The major downfall is that it doesn't work well with non-numeric keys (i.e. myArray["foo"] = "bar") but if you're only using numeric keys it works great.
You can extend this prototype like this:
http://codepen.io/dustinpoissant/pen/AXbjxm?editors=0011
var MySubArray = function(){
Collection.apply(this, arguments);
this.myCustomMethod = function(){
console.log("The second item is "+this[1]);
};
};
MySubArray.prototype = Object.create(Collection.prototype);
var msa = new MySubArray("Hello", "World");
msa[2] = "Third Item";
console.log(msa);
msa.myCustomMethod();

Categories