I have a variable called "information" which creates a multi-dimensional array. For each row in the array, I want to return a variable whose name is the first value in the array. In other words, given the 'information' array below, I'd want the following output:
var lunalovegood = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Luna Lovegood is a Ravenclaw!;
var dracomalfoy = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Draco Malfoy is a Slythering!;;
var hermionegranger = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Hermione Granger is a Gryffindor!;;
In other words, I want to be able to work with each of the elements in the 'information' array to create some markup. I already know how to get the information I need given the information array, but as you can see below I'd have to declare separate variables for each of the names.
for (var i = 0; i < information.length; i++) {
var htmlString = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Luna Lovegood is a Ravenclaw!
$('div').html(htmlString);
} //end for loop
var information = [
['lunalovegood', 'Ravenclaw', 'Luna', 'Lovegood', '(chaser)', 'lovegood.jpg', 4]
['dracomalfoy', 'Slytherin', 'Draco', 'Malfoy', '(seeker)', 'malfoy.jpg', 2],
['hermionegranger', 'Gryffindor', 'Hermione', 'Granger', '(none)', 'granger.jpg', 3],
];
The javascript below creates three variables called 'lunalovegood', 'dracomalfoy', and 'hermionegrange', but it's the long way of creating variables. How do I create these variables, one for each row in the array, by looping through the 0th indexed element in the 'information' array?
var myVariables = {}
,varNames = ["lunalovegood","dracomalfoy","hermionegranger"];
for (var i=0;i<varNames.length;i+=1){
myVariables[varNames[i]] = 0;
console.log(lunalovegood);
}
Your current approach just needs a most minor tweak to not require the second array.
var students = {}, i;
for (i = 0; i < information.length; ++i)
students[information[i][0]] = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i][1] + '!';
Now the key is set by taking the first item of the Array. You would then do the following for your text,
students['lunalovegood']; // "Luna Lovegood is a Ravenclaw!"
You're also missing a , in your information literal.
This should help you:
Every variable in the global scope can be accessed as a string property of the window object
var myvariable = 4;
alert(window["myvariable"]); // will alert 4
window["newvariable"] = 6;
alert(newvariable); // will alert 6
I agree with Bergi. Variables should represent a fixed finite set of members defined by code; data (as in the contents of a list) should generally not introduce new variables.
As such, here is the approach I would recommend (note that I've added a bit more than the "minimum required"; good luck!):
// Using a function makes it easy to change details and avoid leaking
// variables accidentally.
function loadWizards(information) {
var wizards = [];
for (var i = 0; i < information.length; i++) {
var info = information[i];
var name = info[0];
// Mapping to named properties means we can forget about indices!
wizards[name] = { // <- use Name to map to our Wizard object
house: info[1],
// ..
image: info[7]
};
}
return wizards;
}
// I have no idea if they are wizards, but give variables useful names.
// 'information' is too generic.
var wizards = loadWizards(information);
// Then later on, use it as:
alert("Hello " + wizards['hermionegranger'].name + "!")
// ^-- property access by Name
var formattedInfo = {};
$.each(information, function (i, v) {
formattedInfo[v[0]] = v[2] + ' ' + v[3] + ' is a ' + v[1];
});
there is a missing comma at the end of the 1st line of your definition of information.
BTW, I like Harry Potter very much.
Related
I am creating a store. The way it works is that when I click 'add to cart', I run a function which gets the id of the button. From that id, you can work out the name of the product, get the cost, quantity etc. For simplicity, this is the funciton code:
function getID(a){
var id = a.substring(0, a.length - 4);
var id_quant = document.getElementById(id + '_val').value;
var id_name = document.getElementById(id + '_nme').innerHTML;
console.log(id + " " + id_quant + " " + id_name);
}
You may notice that I remove the last 4 digits from this.id, this is because when I run the PHP to echo all the results, i make the button_id equal to the uid from the database, concatenated with _btn.
What I would then like to do is to push this into an array, or use JSON.
What I am imagining is a nest array like : array[uid][cost], array[uid][name]. I'm just not sure how to do this.
It should be noted that in the function, a is actually this.id:
<button id='1_btn' onclick='getID(this.id)'></button>
I have declared an array above the function, var array = [].
Any help on how to push a nest would be great.
What I would then like to do is to push this into an array, or use
JSON.
You need to use an object
var obj = {};
and set values in this obj from the function as
function getID(a){
var id = a.substring(0, a.length - 4);
var id_quant = document.getElementById(id + '_val').value;
var id_name = document.getElementById(id + '_nme').innerHTML;
obj[ id ] = { quantity : id_quant, name : id_name }; //observe this line
console.log(id + " " + id_quant + " " + id_name);
}
instead of array you should have an object.
var bucket = {};
bucket[someuid] = {
"cost": 500,
"name": "Some Item"
}
Now you can access this simply by,
console.log(bucket[someuid]);
Iterating then is simple
for (item in bucket){ console.log(item['name'], item['cost']) }
I'm looping through results and writing them out to html.
I want to increment the number 1 on the lest side of the equal sign - the binding -
A_Inside_Bus_1_div, A_Inside_Bus_2_div, A_Inside_Bus_3_div etc..
How should I go about that?
for (var i = 0; i <= 4; i++) {
A_Inside_Bus_1_div.innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
A_Inside_Bus_1_Comments_div.innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
Do it like this:
var A_Inside_Bus_div = [];
var A_Inside_Bus_Comments_div = [];
Before you continue the rest, like editing .innerHTML, you need to create those objects. Only after that you can do something like:
for (var i = 0; i <= 4; i++) {
A_Inside_Bus_div[i].innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
A_Inside_Bus_Comments_div[i].innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
This is just an idea how you "should go" about that, as you said.
If those variables are actually the IDs of DIVsm and you're depending on the fact that IDs are turned into global varables, you can use document.getElementById() to access them.
for (var i = 0; i <= 4; i++) {
document.getElementById('A_Inside_Bus_' + (i+1) + '_div').innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
document.getElementById('A_Inside_Bus_' + (i+1) + '_Comments_div').innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
Don't do this. Trying to make variable names to do what you're trying to do just leads to needlessly messy code down the road.
Stick all your elements into arrays:
var elems = [
A_Inside_Bus_1_div
A_Inside_Bus_2_div
...
];
var comments = [
A_Inside_Bus_1_Comments_div
A_Inside_Bus_2_Comments_div
...
];
Then just index the arrays:
for (var i = 0; i <= 4; i++) {
elems[i].innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
comments[i].innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
This is an example of how you could do it with your current setup. Note though, it could be cleaned up. If each element of the elems array always has a partner in comments, it would make more sense to group them together in an object, and only have 1 array.
Also note that populating the arrays in a loop makes more sense. I just hardcoded the arrays here for the sake of brevity. I'm not sure how you're creating the elements originally. They should probably be created and put straight into the array instead of naming them and adding them later.
There are a couple ways you could go about doing this, but they tend to involve some pretty bad habits, like using eval or attaching variables to the global object so you can access them with a string:
var a = 1;
window['a']; //1
But there are better alternatives, the most common is probably storing them in equal-length arrays:
var divs = [div1, div2, div3];
var items = ['cat', 'dog', 'fish'];
items.forEach(function(element, index){
divs[index].innerText = items[i];
});
You could also look at building out a single array of objects:
var objects = [{div: div1, item: 'cat'}, {div: div2, item: 'dog'}, {div: div3, item: 'fish'}];
for object in objects {
object.div.innerText = object.item;
}
I have an array like this:
var array = [
'Hey there, ' + name + '!',
'It\'s nice to see ' + name + ' join us.',
'Everybody welcome ' + name + '!',
'Thanks,' + name
]
I get an error stating that name is undefined, so if I put name = ''; before it, and loop through the array, it just says
Hey there, !
It's nice to see join us.
Everybody welcome !
Thanks,
Is there a way I can do something like:
name = 'Albz'
console.log(array[0]);
and have it echo out
Hey there, Albz!
The name variable is dynamic and changes on each iteration of forEach, so it can't be hardcoded, and I'd like to not have to redeclare the array every single time as it's quite lengthy.
Is there a way to do this?
var nameArr = ['Ayan', 'Arnab', 'Akash'];
function process(name) {
return [
'Hey there, ' + name + '!',
'It\'s nice to see ' + name + ' join us.',
'Everybody welcome ' + name + '!',
'Thanks,' + name
];
}
for (var i = 0, len = nameArr.length; i < len; i += 1) {
console.log(process(nameArr[i])[0]);
}
var myArray = new Array();
var increment = 0;
myArray.push('Tom Hanks', 'Pierce Brosnan', 'Will Smith', 'Richard Ayoade');
for (actor in myArray) {
console.log(actor + ' is my #' + increment + ' choice.');
increment++;
}
Something is wrong with this for loop, and I believe its 'actor' in the for-in loop. This prints out a number where the name of the actor should be.
Coming from Ruby, this looks like a .each method iterating over each element in the array, but obviously this is going about things a bit differently. Can anyone explain why this isn't working?
Just picked up JS today. Thanks.
Thats not how for ... in works. From that link:
A for...in loop iterates over the properties of an object in an arbitrary order
And:
for..in should not be used to iterate over an Array where index order is important. Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that for...in will return the indexes in any particular order and it will return all enumerable properties, including those with non–integer names and those that are inherited.
Given that you are passing in an array the properties are the indexes for the items it holds.
This is why you are getting the index and not the name.
If you want to retain order and print the names, you need a "traditional" for loop, like so:
for (var i = 0; i < myArray.length; i++) {
console.log(myArray[i] + ' is my #' + (i+1) + ' choice.');
}
The reason to be careful when using for .. in is it can have unexpected results. Checkout this jsFiddle...
var myArray = new Array();
var increment = 0;
myArray.push('Tom Hanks', 'Pierce Brosnan');
myArray.hello = "what?";
for (actor in myArray) {
alert(actor + ' is my #' + increment + ' choice.');
increment++;
}
for (var i = 0; i < myArray.length; i++) {
alert(myArray[i] + ' is my #' + (i+1) + ' choice.');
}
In this example, the first loop will iterate 3 times, picking up the 'hello' property as well as the rest in the array. While the second only does the 2 formal items in the array.
In that case, the correct code should be
var myArray = new Array(); var increment = 0;
myArray.push('Tom Hanks', 'Pierce Brosnan', 'Will Smith', 'Richard Ayoade');
for (actor in myArray) {
console.log(myArray[actor] + ' is my #' + increment + ' choice.');
increment++; }
it prints out
Tom Hanks is my #0 choice.
Pierce Brosnan is my #1 choice.
Will Smith is my #2 choice.
Richard Ayoade is my #3 choice.
You are seeing the index of the array element.
Remember that arrays are objects.
When using for(var item in object), var item is the key(property) associated with the value.
You are accessing the arrays properties(indexes), not values.
You should consider using the Array Objects buitin method forEach.
myArray.forEach(function(actor)){
console.log(actor + ' is my #' + increment + ' choice.');
increment++;
});
The simple answer is this: for in loops iterate over properties of an object. An array in JavaScript is an object that's indexed. So, your example is actually this:
Array[4]
0: "Tom Hanks"
1: "Pierce Brosnan"
2: "Will Smith"
3: "Richard Ayoade"
length: 4
__proto__: Array[0]
When you use your for/in code,
for (actor in myArray) {
console.log(actor + ' is my #' + increment + ' choice.');
increment++;
}
actor is the property at the time of iteration (0, 1, 2, 3...)
To access the value in your for in loop would require your code to be updated like this:
for (idx in myArray) {
console.log(myArray[idx] + ' is my #' + idx + ' choice.');
}
However, it's considered bad practice to use for in loops to iterate an array. For example, what if I did something like this:
myArray.type = "Actors";
The console log would return something like:
// 'Actors is my type choice'
Probably not the intended output. Instead, for array iteration, take a look at the for loop or forEach method of arrays.
for (var increment = 0, len = myArray.length; increment < len; increment += 1) {
console.log(myArray[increment] + ' is my #' + increment + ' choice.');
}
// or...
myArray.forEach(function(actor, increment) {
console.log(actor + ' is my #' + increment + ' choice.');
});
As the title says, my onclick event keeps passing the incorrect value - when there is more than one selection displayed, it passes the first and not the selected one. Here's my relevent code.
// my objects
var a = {id:101,name:'John Smith',age:42};
var b = {id:102,name:'Greg Jones',age:40};
var c = {id:103, name:'Clyde Barnes',age:36};
var d = {id:104,name:'John Smith',age:51};
var e = {id:105,name:'Sam Owens',age:40};
var f = {id:106, name:'John Smith',age:36};
// stored as an array
var personIndex = [a, b, c, d, e, f];
// my search function - I pass the value from an html form
function searchName(name) {
'use strict';
var nameMatch = new Array();
for(var i = 0; i < personIndex.length; i++){
if(name==personIndex[i].name){
nameMatch.push(i);
}
}
return nameMatch;
}
So having returned the value(s), I then display a list with buttons below and allow the user to select from many matches. The selected match should pass the index value as a cookie (which I am using an alert to test):
var y ='';
function displayDetail(value){
alert(value); // here is where I would pass the value
}
function displayResult(x){
U.$('results').innerHTML=x;
}
(function(){
'use strict';
var cookie = COOKIE.getCookie('nameIndex');
var c = [];
c = cookie.split('|');
for(var i=0;i<c.length;i++){
var x='<br>Id: ' + personindex[c[i]].id +
'Name: ' + personindex[c[i]].name +
'Age: ' + personindex[c[i]].age +
' <button id=' + c[i] + ' value=' + c[i] + ' onclick=displayDetail(' + c[i] + ')>Details</button>';
y += x;
}
displayResult(y);
})();
What happens is this: I search for John Smith, it displays three John Smiths with buttons for each. I select the second one and it passes the value of the first one. If I select the third, it still passes the value of the first one. Can someone show me where I'm going wrong at?