Javascript for loop with variable - javascript

I'm doing some simple javascript learning at the moment and I'm stuck on how to solve this problem. (the basic form comes from Code Academy). The task is to create 3 rabbit objects, each with a different adjective as an attribute. Then, print describeMyself() for each rabbit.
Instead of repeating myself 3 times, I'd like to find a way to solve the problem with a for loop to make it more streamlined/challenging for myself. Here's what I tried:
function Rabbit(adjective) {
this.adjective = adjective;
this.describeMyself = function() {
console.log("I am a " + this.adjective + " rabbit");
};
}
var rabbit1 = new Rabbit(fluffy);
var rabbit2 = new Rabbit(happy);
var rabbit3 = new Rabbit(sleepy);
for (i=1; i<=3; i++){
("rabbit"+i).describeMyself();
}
Obviously, the ("rabbit"+i).describeMyself() is wrong. I want the loop to create "rabbit1", "rabbit2" and "rabbit3". What's the proper syntax here?

First of all, the parameters you are passing will result in undefined. If you want to pass strings, then use quotes to mark them as such. Second of all, creating new instances in a for loop means you will have to store them somewhere else, like in an array for instance.
var rabbits = [];
var descriptions = ['fluffy', 'happy', 'white', 'sleepy', 'dreamy'];
for (var i = 0; i < 5; i++) {
rabbits.push(new Rabbit(descriptions[i]));
}
//Now you have 5 rabbits stored in the rabbits array. Now here's how to make them //egocentric.
for (var i = 0, ii = rabbits.length; i < ii; i++) {
rabbits[i].describeMyself();
}
var rabbit1 = new Rabbit(fluffy);
var rabbit2 = new Rabbit(happy);
var rabbit3 = new Rabbit(sleepy);
For future reference, don't forget to mark strings with single quotes or double quotes for HTML strings. The above should be:
var rabbit1 = new Rabbit('fluffy');
var rabbit2 = new Rabbit('happy');
var rabbit3 = new Rabbit('sleepy');

Since the rabbits global variables, they are properties of the window object, so you could use:
for (i=1; i<=3; i++){
window["rabbit"+i].describeMyself();
}
However,
I'd recommend using the array examples that have been suggested, though, since this is kindof a bad practice. (But nice to know)

Consider this a hackish answer, but provided you're would do this in global context, you could avoid ussing array and refer to your variables on window obejct like this:
var rabbit1 = new Rabbit('fluffy');
var rabbit2 = new Rabbit('happy');
var rabbit3 = new Rabbit('sleepy');
for (i=1; i<=3; i++){
window["rabbit"+i].describeMyself();
}
Not to mention even more hackish and evil approach with eval (just putting it out there for reference):
for (i=1; i<=3; i++){
eval("rabbit"+i+".describeMyself()");
}

consider using an array of variables then use the index to access them like this
function Rabbit(adjective) {
this.adjective = adjective;
this.describeMyself = function() {
console.log("I am a " + this.adjective + " rabbit");
};
}
var rabbit=[];
rabbit[0]= new Rabbit("fluffy");
rabbit[1]= new Rabbit("happy");
rabbit[2]= new Rabbit("sleepy");
for (i=0; i<3; i++){
rabbit[i].describeMyself();
}

Sometimes it's useful to get the object to add itself to an array automatically.
​var rabbits = [];
function Rabbit(adjective) {
this.adjective = adjective;
this.describeMyself = function() {
console.log("I am a " + this.adjective + " rabbit");
};
rabbits.push(this); // all new Rabbits get added to the array rabbits
}
new Rabbit('happy');
new Rabbit('sleepy');
new Rabbit('fluffy');
for (var i = 0; i < rabbits.length; i++) {
rabbits[i].describeMyself();
}
​

You were close, try this:
var attributes = ["fluffy","happy", "sleepy"];
for (i=1; i<=3; i++){
window["rabbit"+i] = new Rabbit(attributes[i]);
}
for (i=1; i<=3; i++){
eval(("rabbit"+i)).describeMyself();
}

You can't refer to the variables directly, but you can put them in an array/object:
var rabbits = [];
rabbits[1] = new Rabbit('fluffy');
rabbits[2] = new Rabbit('happy');
rabbits[3] = new Rabbit('sleepy');
for (var i= 0; i < 3; i++){
rabbits[i + 1].describeMyself();
}

try out this as it works completely fine in order to bring out the perfect result & here is the code:
function Rabbit(adjective) {
this.adjective=adjective;
this.describeMyself = function() {
console.log("I am a " + this.adjective + " rabbit");
};
}
var rabbit1 = new Rabbit( "fluffy");
var rabbit2 = new Rabbit("happy");
var rabbit3 = new Rabbit("sleepy");
rabbit1.describeMyself();
rabbit2.describeMyself();
rabbit3.describeMyself();
The problem is every one stucks & forgets to type "this.adjective=adjective;" i.e the 3rd line of the code due to which u will c an error as some undefined objects...Try out the above code to get the perfect output...its correct.

Related

Quickly and efficiently switch array elements

I am trying to swap the data within these arrays.
My data will look something like this. In production this array can and will be several times bigger.
var data = [
[13.418946862220764, 52.50055852688439],
[13.419011235237122, 52.50113000479732],
[13.419756889343262, 52.50171780290061],
[13.419885635375975, 52.50237416816131],
[13.420631289482117, 52.50294888790448]
]
Currently my switching code looks like the below.
var temp;
for(var i = 0;i < data.length;i++) {
temp = array[i][0];
array[i][0] = array[i][1];
array[i][1] = temp;
}
What I am trying to figure out is if this the most efficient way to do this and/or if any improvements are possible.
Please understand that even the slightest improvement will matter.
I would use a more functional approach:
var switched = data.map(function (arr) {
return [arr[1], arr[0]];
});
If you use ES2015, you can even do that in one line:
const switched = data.map((arr) => [arr[1], arr[0]]);
If you want to stick with a loop:
for(var i = 0; i < data.length; i++) {
data[i] = [data[i][1], data[i][0]];
}
You code looks perfectly fine, and you don't need any further "optimization".
As always, a benchmark is always the good way to find out who is faster:
var arr = (function() {
var res = [];
for(var i = 0; i < 100000; ++i) {
res[i] = [Math.random(), Math.random()];
}
return res;
}());
var swap_in_place = function() {
for(var i = 0; i < arr.length; ++i) {
var tmp = arr[i][0];
arr[i][0] = arr[i][1];
arr[i][1] = tmp;
}
};
var swap_map = function() {
arr = arr.map(function(elem) {return [elem[1], elem[0]]; });
};
var runBench = function(name, f) {
var start = new Date().getTime();
for(var i = 0; i < 50; ++i) {
f();
}
var stop = new Date().getTime();
console.log(name + " took: " + (stop - start));
};
runBench("in_place", swap_in_place);
runBench("map", swap_map);
in my firefox latest (windows 10 x64), I get (quite consistently) 16 for in place, vs 350 for map version, meaning you get a 20x speed down by using map instead of your own version.
You might think this is due to the fact that this snippet is embedded in a iframe and so on, so I ran it in node (4.5.0), which is built on top of V8, and I get the same results:
I think that the Jitter can't be smart enough to properly inline the function in the map version, or deduce it operates on the same memory without side effect. Thefore, the Jitter has to allocate a full new array to store the intermediate results, then loop over it with a function call (meaning register save/restore stall at each iteration), and then either:
copy back the entire data to arr
move the reference (probably what happens), but the garbage collector has to collect the entire temporary array.
The map function might also trigger reallocation of the temporary, which is extremely expensive.

Syntax to build object properties in loop - javascript

I would like to loop through a list of objects and display one property on a graph on the page but I can't seem to get the right syntax to get this data in a loop.
Without the loop this gives an idea of what I want to do:
document.getElementById("v1").innerHTML = zone1.sensor;
document.getElementById("v2").innerHTML = zone2.sensor;
document.getElementById("v3").innerHTML = zone3.sensor;
I can't figure out how to loop through the objects, something like this:
for(i = 1; i < 7; i++) {
document.getElementById("v" + i).innerHTML = ("zone" + i + ".sensor");
}
While that can be done with eval() or new Function (), that's just plain wrong. Put your values in an array and access them by index. If you absolutely have to use independent variables, do:
var arr = [zone1, zone2, zone3];
and then use
arr[i].sensor
I would go this way to avoid the use of eval:
var zone1 = new Object;
var zone2 = new Object;
var zone3 = new Object;
zone1.sensor = "sensor1";
zone2.sensor = "sensor2";
zone3.sensor = "sensor3";
var zones = [zone1, zone2, zone3];
for( var i = 1; i < 4; i++) {
document.getElementById("v" + i).innerHTML = zones[i - 1]["sensor"];
}
<div id="v1"></div>
<div id="v2"></div>
<div id="v3"></div>
Hope it helps!

Loop through array of images in javascript

I'm trying to loop through an array of images but can't seem to get past image 2.
The array should also loop back to 1 when the last image has passed...
var WorkArray = new Array('work/01.png', 'work/02.png', 'work/03.png', 'work/04.png');
var nelements = WorkArray.length;
preload_image_object = new Image();
var i = 0;
for(i=0; i<=nelements; i++) {
preload_image_object.src = WorkArray[i];
}
function cC() {
var nelements = WorkArray.length;
var i = 0;
for(i=0; i<=nelements; i++) {
nelements = WorkArray[i];
}
document.getElementById("work").style.backgroundImage="url('"+WorkArray[i]+"')";
}
You can save the current file and use modulo to run in cyclic manner.
It will look something like that:
var WorkArray = new Array('work/01.png', 'work/02.png', 'work/03.png', 'work/04.png');
var currentImage = 0
function nextImage(){
currentImage = (currentImage + 1) % WorkArray.length;
document.getElementById("work").style.backgroundImage="url('"+WorkArray[currentImage]+"')";
}
You are overwriting nelements with the current element of the loop:
nelements = WorkArray[i];
The following should fix your loops:
var WorkArray = new Array('work/01.png', 'work/02.png', 'work/03.png', 'work/04.png');
var preload_image_object = new Image();
/* Lets get rid of `nelements`, as its just confusing. Get the length here.
* If, for performace reasons you want to use elements, the best way is to reverse
* aka for(var i = WorkArray.length-1; i >= 0 ; i--)
* Also, its simpler to declare the var in your for-loop itself instead of outside of it.
*/
for(var i = 0; i <= WorkArray.length; i++){
preload_image_object.src = WorkArray[i];
}
Also, again for simplifications sake, your application of the background-image could be done inside your for loop as well, and can be made to look cleaner with some spaces and omitting the ' inside your url():
document.getElementById("work").style.backgroundImage = "url(" + WorkArray[i] + ")";

Apply for loop with variable

I am trying to condense my code because I have a lot of repetitive coding happening. I will need to apply this same example many times over. I want to create a for loop but my variable needs to increase as well. Right now I have my variable increasing but I am unable to implement my cell data into the variable. I think I am double assigning var h. I can't figure out how to get around this. Thank you for your help.
For Loop
for (var j = 2; j<15; j++){eval("var polebrea" +j);
var h = ("polebrea" +j)
}
h = document.getElementById("part1Table").rows[10].cells[2].innerHTML;
Code Attempting To Implement
polebrea2 = document.getElementById("part1Table").rows[10].cells[2].innerHTML;
polebrea3 = document.getElementById("part1Table").rows[10].cells[3].innerHTML;
polebrea4 = document.getElementById("part1Table").rows[10].cells[4].innerHTML;
polebrea5 = document.getElementById("part1Table").rows[10].cells[5].innerHTML;
(cont. to 15)
Inserting Variable
<script>document.write(polebrea2)</script>
Ignoring design dogma....use the string index form of property access to set your variables:
// window is a bad place for this....you should probably put it on another object e.g. var polbreas = {};
for (var i = 2; i<15; i++){
window["polbrea"+i] = document.getElementById("part1Table").rows[10].cells[i].innerHTML;
}
While not necessarily good practice to do what you are doing, you could try this:
var createVariable = function( index ){
var variableName = "polebrea" + index;
var objName = document.getElementById("part1Table").rows[10].cells[index].innerHTML;
return (variableName + " = " + objName + ";");
};
for (var j = 2; j<15; j++){
var objToWrite = createVariable(j);
console.log( objToWrite );
}

Programmatically setting the name of a variable

Is there a shortcut for writing the following 100 assignments?
variable_1 = 1;
variable_2 = 2;
variable_3 = 3;
...
variable_100 = 100;
I have tried
for(var i = 1; i <= 100; i++) {
variable_ + i = i;
}
but I get the error message "Invalid left-hand side in assignment". Any ideas?
Here are a few methods:
Method 1: use eval
Here is the most direct method:
for(var i = 1; i <= 100; i++) {
eval("var variable_" + i + " = " + i);
}
variable_1; // => 1
Disclaimer for the above method: I don't think this problem is a good candidate for using eval. If you do use eval, you should never allow user input to go into what you are evaling, or you could open your site to security risks. That mistake is the main reason people say eval is evil.
Method 2: use dynamically generated object properties
This is a much, much better way:
// If you want these variables to be global, then use `window` (if you're
// in a browser) instead of your own object.
var obj = {};
for(var i = 1; i <= 100; i++) {
obj["variable_" + i] = i;
}
obj.variable_1; // => 1
About the note in the comment about using window to create global variables: I would recommend against this, as it is a quick way to pollute your global scope and step on variables unwittingly.
Method 3: use an array
David suggested using an array. This is another great idea, and, depending on what you are trying to do, may be preferred:
var arr = [];
for(var i = 1; i <= 100; i++) {
arr.push(i);
}
arr[0]; // => 1
This will do it:
for(var i = 1; i <= 100; i++) {
eval("variable_" + i + " = " + i + ";");
}
eval is basically evil, but for such purpose it's OK to use it. (reference)
Live test case.
You are better off using an array
var variable = [];
for (var i=1; i <= 100; i++) {
variable[i] = i;
}
Later, you can access the values using variable[1], variable[2] etc.
If it is like that why not to define array of the objects
var a = new Array();
for(i=0;i<100;i+=)
a[i] = i;
Why not using an array instead like this?
<script language="javascript">
var arrayVar = new Array();
for (var i=0; i<100; i++) {
arrayVar["variable_" + i] = i;
}
</script>
Use an array:
var variable = [];
for(var i = 1; i <= 100; i++) {
variable[i] = i;
}
By way of analogy, you'd want to use an array instead of 100 variables for the same reason you'd want
<div class="variable"></div>
<div class="variable"></div>
<div class="variable"></div>
//and so on
instead of
<div id="variable_1"></div>
<div id="variable_2"></div>
<div id="variable_3"></div>
//and so on
<div id="variable_100"></div>
Invalid left-hand side in assignment
This error gets generated because variable_ + i is an expression. The interpreter thinks you are trying to add two variables instead of concatenating a variable name and a string. An expression cannot be on the left-hand side of an assignment operation.
for(var i = 1; i <= 100; i++) {
window["variable_" + i] = i;
}
alert( variable_50 );
alert( variable_34 );
Assuming you're on a browser you can do:
global[variable] = 'hello'
console.log(variable) -> hello

Categories

Resources