I want to loop through an array of objects, check if the name of the object variable is equal to the id of an element passed to the function, and if so set the innerHTML of another object to the name property of the matching object.
ex.
var samplearray = new Array();
var Guy1 = new Object();
Guy1.name = "Bill";
Guy1.health = 100;
samplearray.push(Guy1);
Guy2.name = "Dan";
Guy2.health = 125;
samplearray.push(Guy2);
//this is all done previously by a function on pageload
function afunction(id){
for (item in samplearray)
{
if (item == id.id){
document.getElementById("changeme").innerHTML=samplearray[item].name;
}
}}
"item" in the if doesn't seem to refer to the name of the variable. If i check it with a custom var_dump function, it tells me the value is "11" and not "Guy1". I have no idea why.
edit:
the fixed for loop:
for (var item in samplearray)
{
if (samplearray[item].varname == id.id){
document.getElementById("changeme").innerHTML=samplearray[item].name';
}}
I don't quite understand what you're doing, but here's some comments on your code:
> var samplearray = new Array();
> var Guy1 = new Object();
> Guy1.name = "Bill";
> Guy1.health = 100;
> samplearray.push(Guy1);
> Guy2.name = "Dan";
> Guy2.health = 125;
> samplearray.push(Guy2);
It is considered better style (and a bit tidier) to use object and array initialisers*:
var guy1 = {name: "Bill", health: 100};
var guy2 = {name: "Dan", health: 125};
var samplearray = [guy1, guy2]
Also, variable names starting with a capital letter are, by convention, reserved for constructor functions.
> //this is all done previously by a function on pageload
You need to wait for elements to be available before interacting with them, waiting for the load event is one way of doing that.
> function afunction(id) {
What is id? You seem to treat it like an object later.
Ah, so id is a reference to an element, and id.id should return the element id.
> for (item in samplearray) {
You should declare variables so they do not become globals, so:
for (var item in samplearray) {
It's generally not a good idea to use for..in with an array because the order that members are returned may be different to their index order. Also, it will return all enumerable properties, including those on the prototype chain so you should guard against that if it's not what you want. Much better to use a for loop so you can guarantee the order and avoid non–numeric enumerable properties:
var item;
for (var i=0, iLen=samplearray.length; i<iLen; i++) {
item = samplearray[i];
> if (item == id.id){
So item will be a reference to an Object member of samplearray and id.id is a string so this will always return false, none of the following code will run.
> document.getElementById("changeme").innerHTML=item.name;
In the for..in version, item is a string property name, but you are treating it like an object so this will throw an error and script execution will stop.
In the for loop version, it's a reference to one of the objects in samplearray so the above should "work".
> document.getElementById("changeme").innerHTML=samplearray[item].name;
This should have worked provided item was a numeric property name and not some other enumerable property.
> //neither does this
> } }}
* Intialiser is a general term for an expression that creates an object (such as an Object, Array, Regular Expression, etc.). Where the initialiser uses literal values it may be called a "literal".
var Guy1 = new Object();
In this statement, the Guy1 object has no reference to the string "Guy1". The object exists without the variable. Indeed, the next statement could say:
var friend = Guy1;
and the object Guy1 object would be unchanged.
Besides this, I think you are getting confused about how the for...in loop works. Try reading more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
If you really want your Guy1 object to have a property of "Guy1", you will need to assign it as such:
Guy1.varname = 'Guy1';
And then you can check if (item.varname == id.id) once your for...in loop works correctly.
Related
Please check the code below -
custom_array.push(...) is working
but
custom_array[i] = "n"
is not working.
There are a couple more things which i am not sure why it is not working. Please note the comments with "?" which is not working. Please refer fiddle - http://jsfiddle.net/vc0bbm3d/
The reason that setting items using bracket syntax doesn't work for your object inheriting an array, is that it's not actually an array.
An array has special code for handling property assignment (which is what you do with the bracket syntax) when the property name is an integer. If the index is outside the current length, the length property is adjusted.
When you assign a value to a property in your object, there is no special code to handle the length. The property is just assigned as usual, and the length is never adjusted. As the object already has code for handling what's happening when you use the bracket syntax, the array that it inherts never comes into play.
For the bracket syntax to work in that way, the object has to be an actual array.
try
ar[3] = 2;
ar.length =4
That way it knows you have added something.
Here's an example of what I mean when I say create a layer around the default array object to extend functionality:
var SuperArray = function(){
this.arr = Array.prototype.slice.call(arguments);
};
//abstraction of default array functionality
SuperArray.prototype.set = function(index, value){
this.arr[index] = value;
return this;
};
SuperArray.prototype.unset = function(index){
this.arr.splice(index, 1);
return this;
};
//extension of default array functionality
SuperArray.prototype.consoleList = function(){
var arr = this.arr;
for(var i = 0, l = arr.length; i < l; i++){
console.log(arr[i]);
};
return this;
};
var extArr = new SuperArray(1,2,3);
extArr.set(2, 25); //does array[2] = 25;
extArr.unset(1); //removes array[1]
extArr.consoleList();//console.logs all items in array
extArr.set(2, 25).unset(1).consoleList();//same thing
this simple object accepts arguments and sets them directly into an array, which we then manipulate how we wish. You can then add any utility functions that you need, check for existing array functionality, etc.
Imagine we have this JSON:
{ "A" : {"A1": "1" } }
How can I extract the actual index A1 ?
So that I can use it in JS like:
var index = "A1";
edit — in case you mean, "How can I extract the value at index A1", then you'd just use the dot or bracket operators:
var value = object.A.A1;
or
var index = "A1";
var value = object.A[index];
Else see below.
You can iterate through the property names of an object with the for ... in loop:
for (var propertyName in object) {
// ...
}
The loop will also include properties from the prototype chain, so you can avoid that (if you want) with a function called hasOwnProperty:
for (var name in object) {
if (object.hasOwnProperty(name)) {
// really is a local property
}
}
Newer browsers support a way to get the property names as an array:
var names = Object.keys( yourObject );
That list will only include "own" properties; that is, those for which hasOwnProperty() would return true.
Finally, there are ways that properties can be defined such that they're not "enumerable". Usually when that's done, you would generally not want to see them in for ... in anyway.
Ok, when write like below:
var element = { "name": "" };
var array = [];
for (var i = 0; i < 2; ++i) {
var newelement = element;
newelement.name = i.toString();
array[i] = newelement;
}
Result in:array[0].name == array[1].name == "1".
But write in another way:
var element = { "name": "" };
var array = [];
for (var i = 0; i < 2; ++i) {
var newelement = { "name": i.toString() };
array[i] = newelement;
}
Result in:array[0].name == "0" and array[1].name == "1".
Tell me why.
Because in the second example you are creating a new object on each iteration, but in the first example you are referencing always the same element.
This is a good Javascript question for people to encounter and understand.
In the first block of code, you are assigning newelement a reference to element. Each time through the loop, newelement gets the same reference assigned to it. You aren't creating any new objects, just assigning the same one over and over again.
In the second block of code, you are creating a new object inside the loop so each assignment goes to a different object.
You need to remember that in javascript, assigning an object to a variable only assigns a reference to that object.
var newelement = element; // just assigns a reference to an existing object
Yet, assigning like this is creating a new object:
var newelement = { "name": i.toString() }; // creates a new object
So, in the first code sample, you have array[0] and array[1] each with a reference to the same object. When you modify that object, it affects both array[0] and array[1] since they are both pointing at that object.
In the second code sample, array[0] and array[1] are each pointing at a different object so when you modify one, it does not affect the other.
This is a tricky part of javascript and is something that often trips up C/C++ programmers (it certainly got me when I was first learning JS) who are use to something like the first assignment being a structure copy. Javascript defaults to just assigning a reference unless you're using syntax that specifically creates a new object.
I have a bit of Javascript where I'm POSTing my form with an XMLHttpRequest, which otherwise works fine, but when I try to add the SELECT values to the array of INPUT values, it seems Javascript has lost its mind (or I have).
This function just builds the "name1=value1&name2=value2" string and passes it along.
The code:
function sendTheForm() {
var postData = '';
var inputArr = document.getElementsByTagName('input');
if (inputArr.hasOwnProperty(length)) alert("ARRAY!!");
var selects = document.getElementsByTagName('select');
var tmpObj = new Object();
for (var i = 0; i < selects.length; i++) {
tmpObj.name = selects[i].name;
tmpObj.value = selects[i].value;
inputArr.push(tmpObj);
}
for (var i = 0; i < inputArr.length; i++) {
if (inputArr[i].value) {
if (postData.length) postData += '&';
postData += inputArr[i].name;
postData += '=';
postData += escape(inputArr[i].value);
}
}
makeHttpReq(postData)
}
The error I get in FireFox is: "inputArr.push is not a function" It does say it's an Array.
Now, besides the fact that it's a method (not a function), it seems something is going badly wrong here, it's right under my nose and I can't see it. Help?
Earlier, I tried doing:
len = inputArr.length;
inputArr[len].name = ...
and also got an error that inputArr[31] was undefined. This is probably obvious, but I'm not seeing it. Help?
Having a .length property does not mean that it is an array. getElementsByTagName() returns a DOM 2 NodeList, not an Array.
As Phrogz already said, checking for a length property is NOT a way of checking for an array.
There's only one way to do that, so it works in ALL cases.
And that is using Object.prototype.toString.call(object).slice(8, -1).
Which gives you the Class value.
Value Class Type
-------------------------------------
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
The reason why this isn't working is because the inputArr variable is actually a node list, not a real array.
If you do want it to be an array, you'd loop through it and add all the nodes in it to a real array or you can do this:
var node_array = Array.prototype.slice.call(node_list);
I am trying to remove an element from a Javascript associtive array using the value to find it, but I am having trouble. I have tried splice and JQuery's grep method and neither have worked for me. This is what I currently have.
var array_path = new Array();
function bulk_upload(){
var temp_array = new Object();
for (var i = 1; i<8; i++){
temp_array[i] = $('#path' + i).val();
if(temp_array[i]!='' && temp_array[i]!=null){
array_path['path' + i] = $('#path' + i).val();
}
}
process_txt();
}
function process_txt(){
//alert(array_path.indexOf(full_path)); //returns nothing
var removed_element = array_path.splice(getKey(array_path), 1);
//array_path = $.grep(array_path, function(val) { return val != full_path; });
alert(removed_element);//return nothing, just blank alert box
}
function getKey(data) {
for (var prop in data)
return prop;
}
The way to do this is to use the delete operator.
delete array_path[getKey(array_path)]
Some Background Information
In JavaScript, almost everything descends from Object.prototype. JavaScript, being an open and dynamic language allows you to create/modify properties of objects by simple assignment. This is very similar to what an associative array -- a structure that contains keyed values.
Under the hood an array is just an object that descends from Array.prototype with numeric keys and a special property called length. The length property just returns one greater than the highest numeric property. In essence, an Array is an object with different semantics.
If you're wanting an associative array then Array is not the object you want to descend from. You would want to descend directly from Object. There are two ways to do that, you could either use the new operator or an empty object literal. The syntax for both is below:
var o = new Object();
var o = {};
The second is preferred since it's a little bit more concise.
I wrote a blog post about this a while back, have a look if you want a little bit more info.
There is no such thing in JavaScript as an "associative array" per se. The data structure which corresponds to this concept is simply a JavaScript Object.
Of course, a JavaScript Array (like essentially everything in JavaScript) is an Object, but one with additional capabilities. So you can use an Array as a key-value map, but it's really not the correct structure for that.
To remove a key from an Object, you just do something like this:
var myObj = {};
var myKey = "blah";
myObj[myKey] = 1234; // Adds or updates value for "blah" to 1234.
delete myObj[myKey]; // Removes key-value pair for "blah".
Have you tried delete hash.someKey; ?
You can give your object a remove method, or use apply or call to use another object's remove method, if defined.
function myObj(members){
for(var p in members) this[p]= members[p];
}
myObj.prototype.remove= function(val){
for(var p in this){
if(this[p]=== val) delete this[p];
}
return this;
}
myObj.prototype.toString= function(){
var A= [];;
for(var p in this){
if(this.hasOwnProperty(p)){
A.push(p+':'+this[p])
}
}
return '{'+A.join(', ')+'}';
}
var O= new myObj({a: 1, b: 10, c: 100});
alert(O)
O.remove(10);
alert(O)
I'm not psychic, so I can only guess that you wanted to accomplish something like this:
var paths = [];
function getPaths() {
for(var i = 1; i < 8; ++i) {
var value = $('#path' + i).val();
if(value) paths.push(value);
}
}
function process() {
var firstPath = paths.shift();
// do stuff
}
getPaths();
if(paths.length) process();