Code doesn't work in foreach - javascript

Here is my code:
var divarray = document.getElementById("yui-main").getElementsByTagName("div");
var articleHTML;
var absHTML;
var keyHTML;
var bodyHTML = [];
for( var i in divarray) {
if(divarray[i].className == "articleBody"){
articleHTML = divarray[i];
for( var j in articleHTML ){
bodyHTML[i] = '';
if(articleHTML[j].className == "issueMiniFeature"){continue;}
if(articleHTML[j].className == "abstract"){absHTML = articleHTML[i]; continue;}
if(articleHTML[j].className == "journalKeywords"){keyHTML = articleHTML[i]; continue;}
bodyHTML[i] = articleHTML[i];
}
break;
}
i++;
}
The error I am getting is:
SyntaxError: Unexpected token var
I am using Google Chrome

The javascript for...in doesn't do what you would expect (which is enumerate through eleemnts in an array.
for...in in javascript will enumerate through the key/value pairs (or public variables) that make up the object (which isn't what you want).
You need to use a good, old fashioned for loop.

You can add this to your script:
Array.prototype.foreach = function (callback) {
for (var i=0; i < this.length; i++) {
callback(this[i]);
}
}
Then you simply do this:
myarray.foreach(function (currentItem) {
/*...do whatever with the currentItem...*/
});

I think you mistaking JavaScript for the functionality of PHP. JavaScript does not have foreach loops. JavaScript has for in, which is what you are incorrectly using and normal for loops. Use a standard for loop when dealing with arrays. You will need to use a for in loop with object literals because the index is not the simplicity of an incrementing positive integer.
In JavaScript a for loop has 3 parts in its argument separated by a semicolon as follows:
* start position of incrementor (optional if the variable is previous defined with 0 or a positive integer)
* end position of incrementor
* method of incrementation
In the following examples arrayName is value I made up for the name of an array:
for (; a < arrayName.length; a += 1) {
for (a = x + 1; a < arrayName.length + 3; a += 2) {
The for in loop argument has two required parts and a third part to prevent errors using an if condition:
* The value of an index to search for
* The name of the container in which to search
* The third part is an if condition
The following example will return the value supplied to the "book" index of the objectName object literal. objectName is a name I made for an example object literal:
for ("book" in objectName) {
if (objectName.hasProperty("book")) {

Why not use a traditional for loop instead? You're not really using an associative array here ...

That's not the right way to iterate over a collection.
You want a standard for loop, not a for..in loop
for( var i = 0, l = divarray.length; i < l; i++ ) {
There's something else, you then proceed to try to iterate over each element
for( var j in articleHTML ){
articleHTML at this point holds a reference to a single HTML node - not a collection or array of any sort.

Related

How to Loop Through ths Array in JavaScript

I'm new to Javascript and I am begining to learn.
I need help understanding; how can I retrieve each carachter of this array.
var possibleRaysPasswords =['mobleyAndTrentonAreDead','tyrellIsElliot','dreadPirateRoberts'];
Like in these example:
e.g: femtocell
f
fe
fem
femt
femto
femtoc
femtoce
femtocel
femtocell
Much appreciated.
If you want to get each character of each element, you may do a simple array transformation to get you an array of all the characters in all the items:
var allOfThem = arr.join('').split('');
That is: you first join all the elements into a single string. and then you split this string into array of characters. Then you can loop over it.
Can you provide an example of what you've tried so far? Doing so will help us to answer any confusion you have.
For a start, let's demonstrate how to loop through each element in the array. We can declare an array the way you demonstrated:
var myArray = ["elements", "are", "pretty", "cool! "];
To loop through this array, we can simply use a for loop.
for (var i = 0; i < myArray.length; ++i) {
console.log(myArray[i]); // this provides the element at the ith index of the array
}
This will log, in order:
elements
are
pretty
cool!
You can access the individual characters of a string in the same exact way that you access individual elements of an array. Try that and see if you can get to where you need to be.
You could use two nested loop, one for the array and one for the atrings for the letters in combination with String#slice
var possibleRaysPasswords =['mobleyAndTrentonAreDead','tyrellIsElliot','dreadPirateRoberts'],
i, j;
for (i = 0; i < possibleRaysPasswords.length; i++) {
for (j = 1; j <= possibleRaysPasswords[i].length; j++) {
console.log(possibleRaysPasswords[i].slice(0, j));
}
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Let me know if something is unclear. The comments in the code should tell you what's going on though:
// making this a constant, because we only want to read from this data
const passwords = ['mobleyAndTrentonAreDead', 'tyrellIsElliot', 'dreadPirateRoberts'];
// somewhat recently, we can also define functions like this
const printPassword = password => {
// this function prints out the password starting from the first character, all the way to its end
// if the password is 'test', the output should be 't te tes test'
let resultString = ''; // this will be returned later
// let's use the good old for loop
// start at the first character (zero-indexed), and use the counter variable i to mark the end of the substring
for (let i=1; i <= password.length; i++) {
resultString += password.substring(0, i) + ' ';
}
return resultString;
};
// iterating over every password in the passwords array,
// and log the returned string to the console
passwords.forEach(password => console.log(printPassword(password)));
user 'forEach' to iterate elements of array and 'substr' to part of string:
var possibleRaysPasswords =['mobleyAndTrentonAreDead','tyrellIsElliot','dreadPirateRoberts'];
possibleRaysPasswords.forEach(function(element){
for(var i=0 ; i<element.length ; i++){
console.log(element.substr(0,i));
}
});
'for of' can also be used for iteration:
for (element of possibleRaysPasswords){
for(var i=0 ; i<element.length ; i++){
console.log(element.substr(0,i));
}
}
As simple as that:
var letters = [];
for(let i of possibleRaysPasswords ){letters.push.apply(letters,i.split(""))}
console.log(letters);
That will create and array with all letters. Not sure if that was the question though

Javascript checking whether string is in either of two arrays

I'm pulling my hair out over this one. I have two arrays, likes & dislikes, both filled with about 50 strings each.
I also have a JSON object, data.results, which contains about 50 objects, each with an _id parameter.
I'm trying to check find all the objects within data.results that aren't in both likes and dislikes.
Here's my code at present:
var newResults = []
for(var i = 0; i<data.results.length; i++){
for(var x = 0; x<likes.length; x++){
if(!(data.results[i]._id == likes[x])){
for(var y = 0; y<dislikes.length; y++){
if(!(data.results[i]._id == dislikes[y])){
newResults.push(data.results[i]);
console.log("pushed " + data.results[i]._id);
}
else
{
console.log("They already HATE " + data.results[i]._id + " foo!"); //temp
}
}
}
else
{
console.log(data.results[i]._id + " is already liked!"); //temp
}
}
}
As you can see, I'm iterating through all the data.results objects. Then I check whether their _id is in likes. If it isn't, I check whether it's in dislikes. Then if it still isn't, I push it to newResults.
As you might expect by looking at it, this code currently pushes the result into my array once for each iteration, so i end up with a massive array of like 600 objects.
What's the good, simple way to achieve this?
for (var i = 0; i < data.results.length; i++) {
isInLiked = (likes.indexOf(data.results[i]) > -1);
isInHated = (dislikes.indexOf(data.results[i]) > -1);
if (!isInLiked && !isInHated) {
etc...
}
}
When checking whether an Array contains an element, Array.prototype.indexOf (which is ECMAScript 5, but shimmable for older browsers), comes in handy.
Even more when combined with the bitwise NOT operator ~ and a cast to a Boolean !
Lets take a look how this could work.
Array.prototype.indexOf returns -1 if an Element is not found.
Applying a ~ to -1 gives us 0, applying an ! to a 0 gives us true.
So !~[...].indexOf (var) gives us a Boolean represantation, of whether an Element is NOT in an Array. The other way round !!~[...].indexOf (var) would yield true if an Element was found.
Let's wrap this logic in a contains function, to simply reuse it.
function contains (array,element) {
return !!~array.indexOf (element);
}
Now we only need an logical AND && to combine the output, of your 2 arrays, passed to the contains function.
var likes = ["a","b","f"] //your likes
var dislikes = ["c","g","h"] //your dislikes
var result = ["a","c","d","e","f"]; //the result containing the strings
var newresult = []; //the new result you want the strings which are NOT in likes or dislikes, being pushed to
for (var i = 0,j;j=result[i++];) //iterate over the results array
if (!contains(likes,j) && !contains (dislikes,j)) //check if it is NOT in likes AND NOT in dislikes
newresult.push (j) //if so, push it to the newresult array.
console.log (newresult) // ["d","e"]
Here is a Fiddle
Edit notes:
1. Added an contains function, as #Scott suggested
Use likes.indexOf(data.results[i]._id) and dislikes.indexOf(data.results[i]._id).
if (likes.indexOf(data.results[i]._id) != -1)
{
// they like it :D
}
Try first creating an array of common strings between likes and dislikes
var commonStrAry=[];
for(var i = 0; i<likes.length; i++){
for(var j=0; j<dislikes.length; j++){
if(likes[i] === dislikes[j]){
commonStrAry.push(likes[i] );
}
}
}
then you can use this to check against data.results and just remove the elements that don't match.

JQuery for loop

I need to Loop in JQuery from 0 to variable-value(dynamically entered by user).How can i achieve this?
Now i am doing it by using simple For loop like this.
for( i=1; i<=fetch; i++) {
var dyndivtext = document.createElement("input");
document.body.appendChild(dyndivtext);
}
Thanks.
You could loop an empty array:
$.each(new Array(fetch), function(i) {
var dyndivtext = document.createElement("input");
document.body.appendChild(dyndivtext);
});
If you do this alot you can even fake-patch jQuery.each to take numbers:
(function($) {
var _each = $.each;
$.each = function() {
var args = $.makeArray(arguments);
if ( args.length == 2 && typeof args[0] == 'number') {
return _each.call(this, new Array(args[0]), args[1]);
}
return _each.call(this, args);
};
}(jQuery));​
$.each(fetch, function(i) {
// loop
});
jQuery.each does have some great features, like the different return values inside the callback. But for a simple loop I find it much more convenient (and less overhead) to do something like:
while(fetch--) {
// loop
}​
To loop between two values you should use a regular Javascript loop. The jQuery each methods are used when looping through a collection of elements or an array.
To loop from zero, you should initialise the loop variable to zero, not one. To loop from zero to the specified value, you use the <= for the comparison, but to loop from zero and the number of items as specified (i.e. from 0 to value-1), you use the < operator.
for (i = 0; i < fetch; i++) {
$('body').append($('<input/>', { type: 'text' }));
}
You mean Javascript loop.
From W3Schools:
for (var variable = startvalue; variable < endvalue; variable = variable + increment)
{
//code to be executed
}
To get the value from user and run the code you can use the following prompt.
var x=prompt("Enter the value",0);
for(i=0;i<x;i++)
{
var dyndivtext = document.createElement("input");
document.body.appendChild(dyndivtext);
}
Hope this helps.
Thanks
If you want it the full jQuery way then use that new plugin jQuery-timing. It provides inline-loops in your jQuery line:
$('body').repeat().append('<input>').until(fetch);
Nice, eh?

Shorthand for loop passing three times even if array lenght is 1?

I have this javascript function in external .js file:
function init() {
var v = document.getElementsByTagName('video'),i;
console.log(v.length);
for (i in v) {
console.log("class:" + v[i].className + "id:" + v[i].id);
}
}
init();
And one video element in dedicated html page. This is what script returns to Chrome console:
1 // v.length
class:video1id:bigBunny //first pass of for loop
class:undefinedid:undefined //??
class:undefinedid:undefined //??
Why is this happening?
A NodeList (returned by getElementsByTagName) has not only the elements but two additional properties:
length (the amount of elements)
item (to get an element, basically the same as using [i] notation)
You're iterating them as well and treating as if they are elements. They're not; they don't have a class nor an ID. You should use a numeric for loop (for(var i = 0; i < v.length; i++) instead. This (unlike for in) obviously can't include such properties.
You should really be using a traditional for loop anyway.
for(var i = 0; i < v.length; i++)
{
console.log("class:" + v[i].className + "id:" + v[i].id);
}

Can I select 2nd element of a 2 dimensional array by value of the first element in Javascript?

I have a JSON response like this:
var errorLog = "[[\"comp\",\"Please add company name!\"],
[\"zip\",\"Please add zip code!\"],
...
Which I'm deserializing like this:
var log = jQuery.parseJSON(errorLog);
Now I can access elements like this:
log[1][1] > "Please add company name"
Question:
If I have the first value comp, is there a way to directly get the 2nd value by doing:
log[comp][1]
without looping through the whole array.
Thanks for help!
No. Unless the 'value' of the first array (maybe I should say, the first dimension, or the first row), is also it's key. That is, unless it is something like this:
log = {
'comp': 'Please add a company name'
.
.
.
}
Now, log['comp'] or log.comp is legal.
There are two was to do this, but neither avoids a loop. The first is to loop through the array each time you access the items:
var val = '';
for (var i = 0; i < errorLog.length; i++) {
if (errorLog[i][0] === "comp") {
val = errorLog[i][1];
break;
}
}
The other would be to work your array into an object and access it with object notation.
var errors = {};
for (var i = 0; i < errorLog.length; i++) {
errors[errorLog[i][0]] = errorLog[i][1];
}
You could then access the relevant value with errors.comp.
If you're only looking once, the first option is probably better. If you may look more than once, it's probably best to use the second system since (a) you only need to do the loop once, which is more efficient, (b) you don't repeat yourself with the looping code, (c) it's immediately obvious what you're trying to do.
No matter what you are going to loop through the array somehow even it is obscured for you a bit by tools like jQuery.
You could create an object from the array as has been suggested like this:
var objLookup = function(arr, search) {
var o = {}, i, l, first, second;
for (i=0, l=arr.length; i<l; i++) {
first = arr[i][0]; // These variables are for convenience and readability.
second = arr[i][1]; // The function could be rewritten without them.
o[first] = second;
}
return o[search];
}
But the faster solution would be to just loop through the array and return the value as soon as it is found:
var indexLookup = function(arr, search){
var index = -1, i, l;
for (i = 0, l = arr.length; i<l; i++) {
if (arr[i][0] === search) return arr[i][1];
}
return undefined;
}
You could then just use these functions like this in your code so that you don't have to have the looping in the middle of all your code:
var log = [
["comp","Please add company name!"],
["zip","Please add zip code!"]
];
objLookup(log, "zip"); // Please add zip code!
indexLookup(log, "comp"); // Please add company name!
Here is a jsfiddle that shows these in use.
Have you looked at jQuery's grep or inArray method?
See this discussion
Are there any jquery features to query multi-dimensional arrays in a similar fashion to the DOM?

Categories