In javascript, how would one generate a sequence of vars and set them all equal to a specific function?
for example, I want to create 20 variables that increment by one consecutive integer:
var color1 = getRandomColor()
var color2 = getRandomColor()
var color3 = getRandomColor()...
and so on, and then set each equal to the same function
I understand generating variables could be done with the function below but how would one set search these output variables to the getRandomColor() function within a function?
function createVariables() {
var colors = [];
for (var i = 0; i <= 20; ++i) {
colors[i] = "color" + i;
}
return colors;
}
You can create properties dynamically using Bracket notation.
//Define a object
window.colors = {}
for (var i = 0; i < 20; ++i) {
window.colors["color" + i] = i; //getRandomColor();
}
console.log(window.colors.color0, window.colors)
However I would recommend you to create an array and use its index
var colors = [];
for (var i = 0; i < 20; ++i) {
colors[i] = i; //getRandomColor();
}
console.log(colors[0], colors)
Related
I'm asking for help to find the sum of an array with elements that were pushed from a counter variable that had previously looped 10 times. I'm new to Javascript and was practicing for an assessment, and I've tried several different ways to do it and have only resulted with just a list of the elements within the numbers array.
var counter = 10;
var numbers = [];
for (i = 1; i <= 10; i ++) {
counter = [i + 73];
numbers.push(counter);
}
console.log(numbers);
function sum(arr) {
var s = 0;
for(var i = 0; i < arr.length; i++) {
s = s += arr[i];
}
return s;
}
console.log(sum([numbers]));
function getArraySum(a) {
var total = 0;
for (var i in a) {
total += a[i];
}
return total;
}
var numbers = getArraySum([numbers]);
console.log(numbers);
you should push only the value of counter without the brackets and then make a reduce to have the sum of each number in the array
var counter = 10;
var numbers = [];
for (i = 1; i <= 10; i++) {
counter = i + 73;
numbers.push(counter);
}
console.log(numbers.reduce((a,b) => a+b));
You had a couple of typos in the code:
Typos
You were wrapping the sum in square brackets:
counter = [i + 73];
You should just remove the brackets like:
counter = i + 73;
2. You were wrapping a value that is already an array in square brackets while passing it as an argument to a function:
sum( [numbers] )
// ...
getArraySum( [numbers] );
You should remove the brackets, like this:
sum( numbers );
// ...
getArraySum( numbers );
Fix
I updated the code that you shared to fix the above-mentioned things:
var numbers = [];
// Loop 10 times and push each number to the numbers array
for (var i = 1; i <= 10; i ++) {
var sumNumbers = i + 73;
numbers.push(sumNumbers);
}
console.log(numbers);
function sum(arr) {
var total = 0;
for(var i = 0; i < arr.length; i++) {
total += arr[i];
}
return total;
}
// Call the function by passing it the variable numbers, holding an array
var result1 = sum(numbers);
console.log( result1 );
function getArraySum(a) {
var total = 0;
for (var i in a) {
total += a[i];
}
return total;
}
var result2 = getArraySum(numbers);
console.log(result2);
This is what I have currently but I cant get v(i) to behave the same as v1. What am I doing wrong?
I've also tried the piece below which also did not work.
var x = "v" + i;
alert(x);
My main problem is the following:
var v1 = document.getElementById("thing1").innerHTML; // = 100
var v2 = document.getElementById("thing2").innerHTML; // = 150
var v3 = document.getElementById("thing3").innerHTML; // = 200
for (i = 0; i < 4; i++) {
if ( v(i) != ""){
alert(v(i));
}
}
Thanks in advance:)
What you are trying to do is not easily accomplished. You would have to assign the variable to the window object and then print it from there.
A much better solution is to use your own object or array to handle this:
var v1 = document.getElementById("thing1").innerHTML; // = 100
var v2 = document.getElementById("thing2").innerHTML; // = 150
var v3 = document.getElementById("thing3").innerHTML; // = 200
var array = [v1,v2,v3];
for (i = 0; i < 4; i++) {
if ( array[i] != ""){
alert(array[i]);
}
}
All global variables are properties of window object you could use window['v'+ i] or this['v'+ i] to create them.
But this is very bad pattern consider using object instead.
What you are trying to do is get an interpolated variable name, which is not possible in javascript the way you do it.
You can do this using this['v'+i] or window['v'+i] which are both bad ideas in the global scope.
v(i) actually means: run function v(...) with parameter i
If i would write your example code in easy to understand javascript, i would come up with this:
for(var i = 1; i <= 4; i++)
{
var html = document.getElementById('thing'+i).innerHTML;
alert(html);
}
If you want your values in an array, in a way that you don't write the same code 6 times:
var ids = ['thing1','thing2','thing3','thing4'];
// es5
var values = [];
for(var i = 0; i < ids.length; i++)
{
var html = document.getElementById( ids[i] ).innerHTML;
values.push( html );
}
// values now contains all the values of the elements
// OR es 6
var values = ids.map(function(id) { return document.getElementById(id).innerHTML; });
// or
var values = ids.map(id => document.getElementById(id).innerHTML);
You could use an array without using single variables and loop it.
var array = [
'100', // document.getElementById("thing1").innerHTML,
'150', // document.getElementById("thing2").innerHTML,
'200' // document.getElementById("thing3").innerHTML
],
i;
for (i = 0; i < array.length; i++) {
if (array[i] !== "") {
console.log(array[i]);
}
}
If you need some keys, you could use an object.
var object = {
v1: '150', // document.getElementById("thing1").innerHTML,
v2: '200', // document.getElementById("thing2").innerHTML,
v3: '250', // document.getElementById("thing3").innerHTML
},
i;
for (i = 1; i <= 3; i++) {
if (object['v' + i] !== "") {
console.log(object['v' + i]);
}
}
I'm attempting to emulate an infinite looping chaser on an LED strip with Javascript.
What I'm trying to accomplish:
Only use loops or recursive functions. No fancy JS.
Support any length of LED strip (var ledLength)
Support of multiple chasers
Support any number of LEDs (var ledDepth) with any number
of spaces separating the chasers (var blankDepth)
Loop infinitely
No magic numbers
I have this working for 1 chaser:
$(function(){
var ledLength = 20;
for(var i = 0; i < ledLength; i++) {
$('#led').append($('<div>').addClass('node'));
}
$('#led').css('width', ($('.node').length + 1) * $('.node').last().outerWidth(true));
var colors = ['green', 'red', 'blue'];
// add a "clearing" color
colors.push('black');
var ledDepth = 3;
var blankDepth = 2;
var chaserSize = ledDepth + blankDepth;
var iteration = 0;
var loop = setInterval(animate, 250);
function animate() {
if(iteration == ledLength + ledDepth) iteration = 0;
var offset = iteration < chaserSize ? iteration : chaserSize;
for(var i = 0; i <= offset; i ++) {
var colorOffset = i < ledDepth ? i : ledDepth;
$('.node').eq(iteration-i).css('background', colors[colorOffset]);
}
iteration++;
}
});
Or you can view it on the JSBin.
How would I go about tracking multiple chasers on a strip? Meaning after the initial chaserSize has been created and is moving to the right, another would be created and move long with it and loop infinitely.
Any help in to the right direction would be greatly appreciated.
I decided to take a different approach to this using an array.push method.
Basically, I continue to add points, loop through them all to increase their location, and remove them if their location is greater than the length of the strip.
This works for all LED lengths, chaser sizes (colors + blanks between each chaser).
Code:
$(function(){
// create the strip
var ledLength = 30;
for(var i = 0; i < ledLength; i++) {
$('#led').append($('<div>').addClass('node'));
}
$('#led').css('width', ($('.node').length + 1) * $('.node').last().outerWidth(true));
var points = [];
var colors = ['green', 'red', 'blue', 'pink', 'orange', 'purple'];
var ledDepth = colors.length || 6;
var blankDepth = 2;
var chaserSize = ledDepth + blankDepth;
// push blank nodes on the back of colors array
for(var i = 0; i < blankDepth; i++) {
colors.push('blank');
}
var iteration = 0;
// loop!
var loop = setInterval(animate, 100);
function animate() {
if(points.length) {
for(var i = 0; i < points.length; i++) {
// increase each pin by 1
points[i].pin++;
// remove point if pin is greater than led length
if(points[i].pin > ledLength) {
points.splice(i, 1);
}
}
}
if(iteration < chaserSize) {
points.push({pin: 0, color: colors[iteration]});
}
// draw points
for(var i = 0; i < points.length; i++) {
if(points[i].color == 'blank') { // this if for 'resetting'
$('.node').eq(points[i].pin).css('background', 'black');
} else { // this is for changing color
$('.node').eq(points[i].pin).css('background', points[i].color);
}
}
// iterate before reset
iteration++;
// reset sub-iterator (creator)
if(iteration >= chaserSize) {
iteration = 0;
}
}
});
Or JSBin
In Javascript, I have a matrix with a variable number of rows and columns, which I wish to store in a multi-dimensional array.
The problem is that I need extra 3 columns and 3 extra rows with negative indexes in the matrix too. So the result for a 10x10 matrix should be a 13x13 array with indexes from -3 to 9.
I define the array with:
var numberofcolumns = 10;
var numberofrows = 10;
var matrix = [];
for (var x = -3; x < numberofcolumns; x++) {
matrix[x] = [];
}
Is this the right way to do this? Or is there a better way?
While you can create attributes that are negative numbers, you lose some of Javascript's pseudo-array magic. In particular, matrix.length will still be 10 even though it has 13 elements. And the code in general may be surprising to anyone reading it.
You might be better off defining an offset to get the value you need out of the array index and vice-versa:
var offset = 3
for (var x=-3; x<numberofcolumns; x++) {
matrix[x+offset] = []
}
You could define the matrix as an object instead. You would lose some array functionality but you could still access matrix[-3] for example.
var numberofcolumns = 10;
var numberofrows = 10;
var matrix = {};
for (var x = -3; x < numberofcolumns; x++) {
matrix[x] = [];
}
for (x in matrix) {
console.log(matrix[x]);
}
Or you could define your own class starting as an object or array and work from there. Here's something to get you started:
function Matrix() { };
Matrix.prototype.LBound = function()
{
var n;
for (i in this) {
if (!isNaN(i) && (isNaN(n) || n > i))
n = parseInt(i);
}
return n;
};
Matrix.prototype.UBound = function()
{
var n;
for (i in this) {
if (!isNaN(i) && (isNaN(n) || n < i))
n = parseInt(i);
}
return n;
};
Matrix.prototype.length = function()
{
var length = this.UBound() - this.LBound();
return isNaN(length) ? 0 : length+1;
};
Matrix.prototype.forEach = function(callback, indexes)
{
if (!indexes) var indexes = [];
for (var i = this.LBound(); i <= this.UBound() ; i++)
{
indexes[Math.max(indexes.length-1, 0)] = i;
callback(this[i], indexes);
if (this[i] instanceof Matrix)
{
var subIndexes = indexes.slice();
subIndexes.push("");
this[i].forEach(callback, subIndexes);
}
}
};
Matrix.prototype.val = function(newVal)
{
if (newVal)
{
this.value = newVal;
return this;
}
else
{
return this.value;
}
};
Then you'd create your matrix as such
var numberofcolumns = 10;
var numberofrows = 10;
var matrix = new Matrix();
for (var i = -3; i < numberofcolumns; i++) {
matrix[i] = new Matrix();
for (var j = -4; j < numberofrows; j++) {
matrix[i][j] = new Matrix();
matrix[i][j].val("test " + i + " " + j);
}
}
And you can run some cool functions on it
console.log("Upper bound: " + matrix.LBound());
console.log("Lower bound: " + matrix.UBound());
console.log("Length: " + matrix.length());
matrix.forEach(function(item, index)
{
if (item.val())
console.log("Item " + index + " has the value \"" + item.val() + "\"");
else
console.log("Item " + index + " contains " + item.length() + " items");
});
DEMO: http://jsfiddle.net/uTVUP/
I agree with Mark Reed's points about this being a unintuitive use of Array. I think a subclass is in order. You could follow the tutorial here to subclass Array, keep the native bracket notation, and override methods like length() so they give sensible values. Subclassing would have the added advantage of making it clear to those reading your code that something besides your everyday array is going on.
...not sure "calculated" was the right word...I have written two functions, the second of which needs the output of a variable from the first. I cant seem to get it to pass...my guess is that I am calling it wrong, but can't seem to get it right...might have something to do with the time I've spent staring at the whole thing..
The variable I need passed is subset I am trying to use it on the last line of the second function.
If it matters, the getPos function is getting its value from an input box.
The javascript:
<script>
var alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
function getPos(value)
{
var letterPosition = alphabet.indexOf(value);
var subset = alphabet.slice(letterPosition+1, 26);
document.getElementById('theRest').value = subset;
}
function appendTable(id)
{
var tbody = document.getElementById(id).getElementsByTagName("tbody")[0];
var i = 0;
for (var r = 0; r < 4; r++) {
var row = tbody.insertRow(r);
for (var c = 0; c < 4; c++) {
var cell = row.insertCell(c);
cell.appendChild(document.createTextNode(subset[i++]));
}
}
}
</script>
<script>
var alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
var subset;
function getPos(value)
{
var letterPosition = alphabet.indexOf(value);
subset = alphabet.slice(letterPosition+1, 26);
document.getElementById('theRest').value = subset;
}
function appendTable(id)
{
var tbody = document.getElementById(id).getElementsByTagName("tbody")[0];
var i = 0;
for (var r = 0; r < 4; r++) {
var row = tbody.insertRow(r);
for (var c = 0; c < 4; c++) {
var cell = row.insertCell(c);
cell.appendChild(document.createTextNode(subset[i++]));
}
}
}
</script>
That should do the trick.
Declaring subset before the functions makes it a global var, if you define it with var subset within a function it becomes tied to that function, removing the var makes it use the global var.