I'm adding a bunch of input fields into an associative array. I can access the individual elements fine, eg. this works:
arr = new Array();
field = document.getElementById("someField");
arr[field] = someValue;
alert(arr[field].id);
But when I try to loop over them, the id shows up as undefined, and only one element is looped over.
for (var elem in arr) {
alert(elem.id + " " + arr[elem]);
}
Am I looping over it wrong?
Edit: arr.length shows up as 0 for some reason even though I'm able to access its elements.
the key in a javascript-array has to be a number or string.
field is automatically converted to a string with toString().
arr = new Array();
field = document.getElementById("someField");
var key = field.toString();
arr[key] = someValue;
alert(arr[key].id);
in your for-loop, you iterate the keys of that array.
field.toString() in that case.
and a string does not have a id-property.
this will work:
for (var elem in arr) {
alert(arr[elem].id + " " + arr[elem]);
}
by the way toString() of a DOM-Element ist often a generic string like "[SpanElement]".
if you try to add multiple span-elements, you're effectivle overriding the item with "[SpanElement]" as key and end up with just one element.
in respect to #user2736012 comments, i encourage everyone to read
"JavaScript Associative Arrays Demystified"
Any associative array in JavaScript is an object. Arrays are objects that have special methods because they are numerically indexed. So your code should look something like this:
obj = {};
field = document.getElementById("someField");
obj[field] = someValue;
for (var p in obj) {
alert(obj[p].id);
}
Related
I am trying to parse a string in JS with a series of vars inline. The goal is to turn those vars into an object with name value pairs.
Example:
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
I know I can parse the original string to get an array of name value pairs like this:
varArr = hwStr.split("+");
When I print that array I would get:
>color=blue,
>coreCnt=4,
>shell=aluminum,
>wireless=false
In order to create this object manually it would look like:
var hwSpec = {color: 'blue', coreCnt: 4, shell: 'aluminum', wireless: false};
My question is, how can I use a foreach statement to create an object that would have these as name value pairs.
To be fair JS is not my language, but I know that I SHOULD know this... This is probably a noob Question, any help would be great.
Gary C aka the UnKulMunki
After splitting on the plus signs, you can .reduce() the resulting array to process each key=value pair and add to an object:
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
var obj = hwStr.split("+").reduce(function(o, item) {
item = item.split("=");
o[item[0]] = item[1];
return o;
}, {});
console.log(obj);
This is similar to using .forEach(), except instead of creating an empty object in a variable before calling .forEach() the empty object is passed as an argument to .reduce(). For this particular problem it doesn't make much difference, but in some cases .reduce() saves you having to create a temporary working variable.
EDIT: Note that my code creates all property values as strings - I don't think there's any way to know whether false should be treated as the boolean false or the string "false", unless you want to assume that all values that can be parsed as boolean or number should be treated as boolean or number.
First, you split the string at the + so you get an array of key/value pairs.
Then, you loop through those pairs and split each pair at the = to separate the key from the value. Then you assign the key as a property name and the value as the property value.
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
// Split the string into an array of key/value pairs
var pairs = hwStr.split("+");
// Set up a new, empty object
var newObj = {};
// Loop through the key/value pairs array. The .forEach method takes
// a function as an argument that, itself, receives a value representing
// the current array item being iterated (a single key/value pair from
// the array in this case).
pairs.forEach(function(pair){
// Create a new property on the object with the key of the current pair
// and a value of the value of the current pair.
newObj[pair.split("=")[0]] = pair.split("=")[1];
});
console.log(newObj);
To do this, you have to use JSON's parse method to turn the string to javaScript object literal, this is how to do it:
var arr = hwStr.split("+");
var temp_arr = null;
var hwSpec = null;
var stringToConv = '{'; //string to convert to object literal
//iterate through the array
for (var i = 0; i < arr.length; i++){
temp_arr = arr[i].split("=");
stringToConv += '"' + temp_arr[0] + '":"' + temp_arr[1] + '"';
//check if is the last string in the arr
if (i === arr.length - 1){
stringToConv += '}'
}
else { //add comma
stringToConv += ",";
}
}
//convert to object using JSON
hwSpec = JSON.parse(stringToConv);
//your code here
sorry I feel this is sort of a stupid question I have searched quite a bit and I cannot find my answer.
I have an array in JavaScript that I am inserting a bunch of elements. The trouble is I cannot then get the values of the elements back out, I think I am getting the property of the actual array. Below is what I am doing and what I am trying to do. Thanks in advance for the help. This is not the full traverse method, it actually does go through a bunch of times. When I previously just had an associative array items[a] it worked perfectly.
var element = { html: "", group: "" };
var array = [];
function traverse(o) {
for (var key in o) {
element.html = "<li class='item'>" + key + " : </li>";
element.group = b;
array.push(element);
}
}
I want to print the html from each element, the issue is I get the .html from only the first element each time.
function printElements() {
for (item in array) {
var element = array.pop();
console.log(element.html);
}
}
I also tried.
function printElements() {
for (item in array) {
console.log(array.html);
}
}
I want to keep the array intact, I do not want to pop and elements I just want to print them.
The main problem isn't to get the data out of the array, it never gets into the array in the first place.
You don't have a bunch of elements in the array, you only have one element that you change and add to the array over and over. When you put it in the array it's not copied, it's just the reference to the element that is placed in the array. You end up with an array full of references to the same single element.
Create a new element for each iteration in the loop when you populate it:
for (var key in o) {
var element = {};
element.html = "<li class='item'>" + key + " : </li>";
element.group = b;
array.push(element);
}
Use a simple for loop instead:
for (var i = 0; i < array.length; i++) {
var item = array[i];
// do stuff
}
It is unadvisable to use the nicer for loop syntaxes on arrays in JavaScript because they will iterate through all key/value pairs in the array, not just the array numeric keys. This is because arrays are objects, too, and the for...in loop syntax does not differentiate between them.
You're not using the iterated object, instead you are using array... change this:
function printElements() {
for (item in array) {
console.log(array.html);
}
}
to this:
function printElements() {
for (item in array) {
console.log(array[item].html);
}
}
jsfiddle
Do it this way:
var array = [];
function traverse(o) {
for (var key in o) {
var b = 'b'; // if that is what you have ment
var element = { html : "<li class='item'>" + key + " : </li>", group : b};
array.push(element);
}
}
function printElements() {
for (var item=0; item<array.length; item++) {
console.log(array[item].html);
}
}
That's because it isn't safe to use for each in case of arrays and you should have new object for each array element.
Be sure not to use delete on array elements either.
I am trying to set up an array in jQuery and I then need to do a for loop on it. But it seems that I cant use an associative array for some reason?
var items = new Array();
items['foo'] = 123456;
items['bar'] = 789012;
items['baz'] = 345678;
items['bat'] = 901234;
alert(items.length);
This is just a test, but it return 0?
You can't make associative array in JavaScript like what you want, instead you can use Object.
For example:
var items = {
foo : 123456,
bar : 789012,
baz : 345678,
bat : 901234
}
And to calculate the length you can do:
var getObjectSize = function(obj) {
var len = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) len++;
}
return len;
};
Use: getObjectSize(items); // output: 4
For more see here.
Another one is:
Object.keys(items).length;
But not supported by all browsers.
var items = new Array();
items['foo'] = 123456;
The problem lies in the very first line. You believe that you are adding an item to the array at the index foo, but you are actually adding a property to the items variable with a key foo and value 123456. If you were to type items.foo it would give you back your 123456.
The problem with this approach is that adding a property to an array does not magically increase it's length.
If you want to have non-numeric indexes, you need to use an object instead of an array:
var items = {
foo: 123456,
bar: 789012,
baz: 345678,
bat: 901234
};
Another approach might be to set up two different arrays, which you construct in parallel:
var items = [], items2 = [];
items.push('foo');
items2.push(123456);
// etc.
alert(items2.length);
The efficiency of this approach depends on how you'll use it. If you're only going to loop through the list of items and do something to each of them, this approach may be more efficient. But if you need to use it like an associative array (items['foo']), then you're better off building an object.
The .length property returns the highest numerical index of the array. Thus, in your case, there is no numerical index and it returns 0. Try
items[98] = "something";
items.length will be 98..! Use the .length property with caution, and if you also want to count the non-numerical indici, loop over the Object (an Array is also an Object) and count its ownProperties.
Is there a better way to create a two-dimensional array in javascript than this?
var divcookies = new Array();
divcookies[0] = new Array(2);
divcookies[0][0] = name;
divcookies[0][1] = value;
This results in a two dimensional array with bad data added in the middle of it. I expect an array like this.
(name1, value1, name2, value2, name3, value3)
Instead I get this.
(name1, value2, ,name2, value2, name3, value3)
I don't really know when that extra bad data is added because if I alert during the loop that fills the array it only seems to loop through 3 times to put the three pairs of values expected.
So I am looking for a different way to get the two dimensional array.
function get_cookies_array() {
var divcookies = new Array();
if (document.cookie && document.cookie != '') {
var split = document.cookie.split(';');
for (var i = 0; i < split.length; i++) {
var name_value = split[i].split("=");
name_value[0] = name_value[0].replace(/^ /, '');
if ( name_value[0].search("compage") != -1 ) {
alert (divname+" "+ divarray);
divcookies[i] = new Array(2);
divcookies[i][0] = decodeURIComponent(name_value[0]);
divcookies[i][1] = decodeURIComponent(name_value[1]);
}
}
}
alert (divcookies);
return divcookies;
}
jsBin http://jsbin.com/iwuqab
The recommended method for creating arrays in JS is to NOT use the 'new' method. Instead, do:
var divcookies = [];
divcookies[0] = [];
divcookies[0][0] = name;
divcookies[0][1] = value;
This notation frees you up from having to specify element numbers in advance. Once a variable's been initialized as an array, you can set any index you want. The downside (regardless of which notation you use) is that you have to initialize every sub-array as well.
Your 2-dimensional array is set up correctly (well, [] is preferred instead of new Array()). The actual problem is only with the display of your array using alert(divcookies). Here, divcookies is converted to a string using the predefined method toString(). This method creates a list of comma-separated array elements, from the first element to the last element. If some elements in between are not set, an empty string is output. In your case, you are not assigning to those indexes i of divcookies for which name_value[0].search("compage") == -1. These are the gaps ,, in the alerted list.
Object.keys(obj) returns an Array of strings that are the keys of an object.
But what if the object is an array and I want the list of integer indexes that it has?
Is there a simple way to extract this without having to parseInt() them all?
Alternatively, is there a simple way to implement a sort of Object.values() to get an Array of the values (with normal Array integer keys) from an object?
You can loop the array for():
var arr = ["aaaa", "bbbb", "cccc"];
var iArr = [];
for(var i in arr)
{
iArr[i] = i;
alert(i+ " > " + arr[i]);
}
alert(iArr.length);
http://jsfiddle.net/Achilleterzo/kfLzD/
According to the final final final final draft of ES5, it seems that there is nothing like what you are looking for.
I think that all you can do is
var numericKeys = Object.keys(myObject).filter(function (key) {
return parseInt(key, 10).toString() === key;
});