I have the following javascript
information0 = xmlDoc.getElementsByTagName("info")[0].textContent;
information1 = xmlDoc.getElementsByTagName("info")[1].textContent;
information2 = xmlDoc.getElementsByTagName("info")[2].textContent;
information3 = xmlDoc.getElementsByTagName("info")[3].textContent;
information4 = xmlDoc.getElementsByTagName("info")[4].textContent;
information5 = xmlDoc.getElementsByTagName("info")[5].textContent;
information6 = xmlDoc.getElementsByTagName("info")[6].textContent;
I want to create a new var for each index number. There are 600 in total. How can I do this using a for loop?
Thanks in advance
The best thing here is to use an array, not a bunch of individual variables.
var information = [];
var index;
var info = xmlDoc.getElementsByTagName("info");
for (index = 0; index < info.length; ++index) {
information[index] = info[index].textContent;
}
Um... use an array? Also, don't call getElementsByTagName repeatedly, it's expensive!
var tags = xmlDoc.getElementsByTagName('info'), l = tags.length, i, information = [];
for( i=0; i<l; i++) information[i] = tags[i].textContent;
If you're in a reasonably up-to-date browser:
var information = [].map.call(xmlDoc.getElementsByTagName('info'),function(a) {return a.textContent;});
Like this:
var information = [],
i,
elements = xmlDoc.getElementsByTagName("info"),
n = elements.length;
for (i = 0; i < n; ++i) {
information[i] = elements[i].textContent;
}
You need to use an array.
var infoTags = xmlDoc.getElementsByTagName("info"),
i = 0,
len = infoTags.length,
values = []; //array literal syntax, you could also use new Array()
for (; i < len; i++) {
values.push(infoTags[i].textContent); //push the textContent into the array
}
Things that you should note:
I cached the result of getElementsByTagName instead of performing the query multiple times.
I cached the length property of infoTags. That avoids multiple property lookups to access infoTags.length on every iterations. Property lookups are expensive in JavaScript.
To know how you can work with arrays, have a look at the Array object.
-
Related
Bit of a theoretical question, if I had a JavaScript application where I have multiple Players and for each player there will be 100 computer generated maths questions.
In single player mode it's easy, just generating the questions for the one player:
var player1Qs = [];
for (i = 0; i < maxQustions; i++) {
// Generate Question Object
var question = {};
...
// Add to Array
player1Qs.push(question);
}
That works with no issue. However, when I add a second player into the mix using the same sort of idea as above is where I get a bit puzzled. I'm tryinng to do it without using a multi-dimensional array becasue I'm trying to keep it as simple as possible, but it might be unavoidable.
So player 2 would look something similar to this:
var player1Qs = [];
var player2Qs = [];
for (i = 0; i < playerCount; i++) {
for (j = 0; j < maxQustions; j++) {
// Generate Question Object
var question = {};
...
// Add to Array
???
}
}
Would there be a way of me adding to those two arrays dynamically using a for loop? Or would I need a containing array of players and inside that an array for the questions?
Something like this should do the trick:
// Make sure all players exist.
var players = [];
for (var i = 0; i < playerCount; i++) {
players.push({ name: "Player " + i, questions: [] });
}
// Create questions
for (var i = 0; i < maxQuestions; i++) {
// Generate Question Object
var question = {};
// Do stuff with this question
// Assign the current question to all players.
for (var j = 0; j < playerCount; j++) {
players[j].questions.push(question);
}
}
I'm tryinng to do it without using a multi-dimensional array becasue I'm trying to keep it as simple as possible
I would argue that having a two-dimentional array is the simplest use-case, as you suggest in your question:
Or would I need a containing array of players and inside that an array
for the questions?
The answer is yes (at least if you want to keep it simple). The players array will keep all the players, and each player can then have 100 questions each.
var maxQustions = 100;
var players= []
var player1Qs = [];
var player2Qs = [];
players.push(player1Qs);
players.push(player2Qs);
for (i = 0; i < players.length; i++) {
for (j = 0; j < maxQustions; j++) {
var question = {};
players[i].push(question);
}
}
follow this approach, I assume you have dynamic players and its array:-
var data = {};
var player = [1,2]
var c = [1,2,3,4,5]
for(j=0;j<player.length;j++)
{
data['players'] = player;
data['questions'] = c
}
console.log(data)
I have both an object and an array:
var elementsArr = [];
var elements = {
polygon: 734,
infoContent: "huhu",
id: 0
}
I am going to have multiple "elements" and push each one into "elementsArr".
for(var i=0; i<20; i++){
elements.id = id +=1;
elementsArr.push(elements);
}
My problem now is how to access a specific "id" within the object elements, within the array elementsArr and pushing this into another array.
I tried this but it doesn't seem to be working:
var ids = [];
for(var m=0; m<elementsArr.length; m++){
if(elements.id == elementsArr[m]){
ids.push(elements.id);
}
How do I do this?
Your code is pushing the same object onto the array over and over again.
One way to fix that would be to write a function to get a new element:
function Element(id) {
return {
polygon: 734,
infoContent: "huhu",
id: id
};
}
for(var i=0; i<20; i++){
elementsArr.push(Element(i));
}
If there are going to be a lot of elements, and the "id" values are all relatively small numbers, you'd be better off storing the elements such that the "id" is also the index:
for (var i = 0; i < 20; i++)
elementsArr[i] = Element(i);
To get the element with "id" 17, then:
var element17 = elementsArr[17];
If you really want to search, however, you can use .find():
var element17 = elementsArr.find(function(elem) { return elem.id === 17; });
or a simple loop:
for (var i = 0; i < elementsArr.length; ++i) {
if (elementsArr[i].id === 17) {
// found it!
}
}
You can extract the "id" values from the array with a simple call to .map():
var ids = elementsArr.map(function(elem) { return elem.id; });
or another for loop:
var ids = [];
for (var i = 0; i < elementsArr.length; ++i)
ids.push(elementsArr[i].id);
There are a couple of ways to do this. If you are able to work in ES6 then a WeakMap would be great.
However, I'm going to give you an ES5 instead.
Option 1 Loop through the data.
If you aren't accessing the data often, then looping through as you've done so may be the best choice.
Option 2 Set up your own index
On the other hand, if you need faster lookup, you can set up your own separate index to look things up.
var elementsLookup = {}; // Create an empty object.
for(var i=0; i<20; i++){
elements.id = id +=1;
elementsLookup[id] = elements; // Stash off a copy
elementsArr.push(elements);
}
Then you can look things up with a
var elem = elementsLookup[2]; // Get the element with an id of 2.
It is easy to do it with Array prototyping. Here is a function findById
Array.prototype.findById = function(id){
for(var x = 0 ; x < this.length; x++){
if(this[x].id == id){
return this[x];
}
}
return false;
}
You can use this function to recieve any id from the array or false if it does not exists
elementsArr.findById(17);
I'm working on Google Script and I'm testing different ways to create two dimensions arrays.
I have created an array like this:
var codes = new Array(6);
for (var i = 0; i < 6; i++) {
codes[i] = new Array(4);
}
codes[0][0]="x";
codes[0][1]="x";
codes[0][2]="x";
codes[0][3]="x";
codes[1][0]="x";
codes[1][1]="x";
codes[1][2]="x";
codes[1][3]="x";
codes[2][0]="x";
codes[2][1]="x";
codes[2][2]="x";
codes[2][3]="x";
codes[3][0]="x";
codes[3][1]="x";
codes[3][2]="x";
codes[3][3]="x";
codes[4][0]="x";
codes[4][1]="x";
codes[4][2]="x";
codes[4][3]="x";
codes[5][0]="x";
codes[5][1]="x";
codes[5][2]="x";
codes[5][3]="x";
And it is working fine.
I read following links here, here and here.
But when I do it like this:
var codes = new Array(6);
for (var i = 0; i < 6; i++) {
codes[i] = new Array(4);
}
codes[0]=["x","x","x","x"];
codes[1]=["x","x","x","x"];
codes[2]=["x","x","x","x"];
codes[3]=["x","x","x","x"];
codes[4]=["x","x","x","x"];
codes[5]=["x","x","x","x"];
It didn't work, so I tried like this:
var codes = new Array([["x","x","x","x"],["x","x","x","x"],["x","x","x","x"],["x","x","x","x"],["x","x","x","x"],["x","x","x","x"]]);
it didn't work either.
When the code don't work, I get no error, just no display of the values.
What am I doing wrong? It looks to be the same code and the two not working ways are recommended in many documentations.
W3schools says that there is no need to use new Array().
For simplicity, readability and execution speed, use literal method ex:
var animals = ["cat", "rabbit"];
Reason why your code was not working is that you're equaling codes inside the loop and after end of loop scope 'codes' is getting only the last set array. Instead you should push those arrays to codes.
var codes = [];
for (var i = 0; i < 6; i++) {
codes.push([i]);
}
console.log(codes)
codes[0]=["x","x","x","x"];
codes[1]=["x","x","x","x"];
codes[2]=["x","x","x","x"];
codes[3]=["x","x","x","x"];
codes[4]=["x","x","x","x"];
codes[5]=["x","x","x","x"];
Better yet, two for loops to create the double array:
var codes = [], // Initiate as array, in Javascript this is actually fastre than using new (I don't know any cases you should use new)
rows = 6,
columns = 6;
for (var i = 0; i < rows; i++){
codes.push([]); // Initiate
for (var j = 0; j < columns; j++){
codes[i][j] = 'x';
}
}
Other idea, pre-initiate an array with the correct columns then copy:
var arrTemp = [],
codes = [],
rows = 6,
columns = 6;
for (var j = 0; j < columns; j++)
arrTemp[i] = 'x';
for (var i = 0; i < rows; i++)
codes.push( arrTemp.slice(0) ); // If you just push the array without slice it will make a reference to it, not copy
Other way to pre-initiate the array with 'x's:
arrTemp = Array.apply(null, Array(columns)).map(function () {return 'x'});
There might be a very simple solution my problem but just not being able to find one so please help me to get to my solution in the simplest way...
The issue here is that I have data being displayed in a tabular form. Each row has 5 columns and in one of the columns it shows multiple values and so that's why I need to refer to a value by something like this row[1]['value1'], row[1]['value2'] & then row[2]['value1'], row[2]['value2'].
I declare the array
var parray = [[],[]];
I want to store the values in a loop something like this
for(counter = 0; counter < 10; counter ++){
parray[counter]['id'] += 1;
parray[counter]['isavailable'] += 0;
}
Later I want to loop through this and get the results:
for (var idx = 0; idx < parray.length; idx++) {
var pt = {};
pt.id = parray[schctr][idx].id;
pt.isavailable = parray[schctr][idx].isavailable;
}
Obviously iit's not working because Counter is a numeric key and 'id' is a string key ..my question how do I achieve this ??
Thanks for all the answers in advance.
JS has no concept of "associative arrays". You have arrays and objects (map). Arrays are objects though, and you can put keys, but it's not advisable.
You can start off with a blank array
var parray = [];
And "push" objects into it
for(counter = 0; counter < 10; counter++){
parray.push({
id : 1,
isAvailable : 0
});
}
Then you can read from them
for (var idx = 0; idx < parray.length; idx++) {
// Store the current item in a variable
var pt = parray[idx];
console.log(pt);
// read just the id
console.log(parray[idx].id);
}
Like I did here
What you want inside your array is just a plain object:
// just a regular array
var parray = [];
for(var counter = 0; counter < 10; counter++){
// create an object to store the values
var obj = {};
obj.id = counter;
obj.isavailable = 0;
// add the object to the array
parray.push(obj);
}
later:
for (var idx = 0; idx < parray.length; idx++) {
var pt = parray[idx];
// do something with pt
}
I have stumbled into several methods of looping in JavaScript, what I like the most is:
for(var i = 0; i < a.length; i++){
var element = a[i];
}
But as tested here (http://www.robertnyman.com/2008/04/11/javascript-loop-performance/), it should probably be written so that the length is only calculated once.
In jQuery there is a .each that you can stick a function. I like this a little better, because I don't have to type the array twice, like in the above solution.
If JavaScript supported macros it would be a piece of cake to roll your own, but sadly it does not.
So what do you guys use?
I've started using iterators where relevant. Performance is reasonable, however more importantly it allows you to encapsulate the looping logic:
function createIterator(x) {
var i = 0;
return function(){
return x[i++];
};
}
Then to use:
var iterator=createIterator(['a','b','c','d','e','f','g']);
iterator();
returns "a";
iterator();
returns "b";
and so on.
To iterate the whole list and display each item:
var current;
while(current=iterator())
{
console.log(current);
}
Be aware that the above is only acceptable for iterating a list that contains "non-falsy" values. If this array contained any of:
0
false
""
null
NaN
the previous loop would stop at that item, not always what you want/expect.
To avoid this use:
var current;
while((current=iterator())!==undefined)
{
console.log(current);
}
Small improvement to the original, to only calculate the array size once:
for(var i = 0, len = a.length; i < len; i++){ var element = a[i]; }
Also, I see a lot of for..in loops. Though keep in mind that it's not technically kosher, and will cause problems with Prototype specifically:
for (i in a) { var element = a[i]; }
Just store the length in a variable first.
var len = a.length;
for (var i = 0; i < len; i++) {
var element = a[i];
}
I know I'm late to the party, but I use reverse loops for loops that don't depend on the order.
Very similar to #Mr. Muskrat's - but simplifying the test:
var i = a.length, element = null;
while (i--) {
element = a[i];
}
You could just always use a while loop, and compute the array limit before hand.
Var max = a.length-1;
var i = 0;
while(i <= max)
{
var element = a[i];
i++;
}
If you have many elements in the array and speed is an issue then you want to use a while loop that iterates from highest to lowest.
var i = a.length;
while( --i >= 0 ) {
var element = a[i];
// do stuff with element
}
I don't use it myself, but one of my colleagues uses this style:
var myArray = [1,2,3,4];
for (var i = 0, item; item = myArray[i]; ++i) {
alert(item);
}
like Ash's answer, this will hit issues if you've got "falsey" values in your array. To avoid that problem change it to (item = myArray[i]) != undefined
I don't see what the problem with using a standard for(;;) loop is.
A little test
var x;
var a = [];
// filling array
var t0 = new Date().getTime();
for( var i = 0; i < 100000; i++ ) {
a[i] = Math.floor( Math.random()*100000 );
}
// normal loop
var t1 = new Date().getTime();
for( var i = 0; i < 100000; i++ ) {
x = a[i];
}
// using length
var t2 = new Date().getTime();
for( var i = 0; i < a.length; i++ ) {
x = a[i];
}
// storing length (pollution - we now have a global l as well as an i )
var t3 = new Date().getTime();
for( var i = 0, l = a.length; i < l; i++ ) {
x = a[i];
}
// for in
var t4 = new Date().getTime();
for( var i in a ) {
x = a[i];
}
// checked for in
var t5 = new Date().getTime();
for( var i in a ) {
if (a.hasOwnProperty(i)) {
x = a[i];
}
}
var t6 = new Date().getTime();
var msg = 'filling array: '+(t1-t0)+'ms\n'+
'normal loop: '+(t2-t1)+'ms\n'+
'using length: '+(t3-t2)+'ms\n'+
'storing length: '+(t4-t3)+'ms\n'+
'for in: '+(t5-t4)+'ms\n'+
'checked for in: '+(t6-t5)+'ms';
console.log( msg );
results in:
filling array: 227ms
normal loop: 21ms
using length: 26ms
storing length: 24ms
for in: 154ms
checked for in: 176ms
So:- for in's take the longest, using the length property (which is a property and doesn't need to be calculated) is nearly as fast as storing it first - which is only a whisker slower than using an integer.
AND a for() is the usual way to loop over an array, which everyone expects and understands.
All of them add a variable to the scope they run in - i - which is a common name for this use and so shouldn't be used for other things. Storing the length first adds another var - l - to the scope, which is unnecesary
So, first you identify the perfect javascript loop, I believe it should look like this:
ary.each(function() {$arguments[0]).remove();})
This may require the prototype.js library.
Next, you get disgustet with the arguments[0] part and have the code be produced automatically from your server framework. This works only if the ladder is Seaside.
Now, you have the above generated by:
ary do: [:each | each element remove].
This comes complete with syntax completion and translates exactly to the above javascript. And it will make people's head spin that haven't used seasides prototype integration before, as they read your code. It sure makes you feel cool, too. Not to mention the gain in geekiness you can get here. The girls love it!