So, i'm looping through the document body searching for all "#result>tbody>tr" objects. I'm then trying to search within those elements to see if any of the names exist, if they do, I would like to delete them. I got it working if I don't loop through the names and use a single object. If I try and loop through the names, it only loops four times and then nothing else happens.
Any ideas?
Edit: Currently there are 30 objects the first loop loops through. When I add the second loop into the mix to see if the sub-objects exist, it will only loop through four and than break the loop. Hope that explains better.
Example: https://jsfiddle.net/8c9p7bp5/1/
var dlList = document.querySelectorAll("#result>tbody>tr");
for (var i = 0, len = dlList.length; i < len; i++) {
var names = ['Test', 'Router', 'IP', 'Mod'];
for (var j = 0, len = names.length; j < len; j++) {
var vi = dlList[i].querySelector("td>br>img[title^='" + names[i] + "']");
if(!dlList[i].contains(vi)) {
//dlList[i].remove();
console.log(dlList[i]);
}
}
}
First mistake of your code that you are using same limit for you nested loop "len", in the first iteration the value becomes 4 that's why it will break the parent loop.
You initialize j but never use it in the inner loop.
Try this instead:
var vi = dlList[i].querySelector("td>br>img[title^='" + names[j] + "']");
Also, you should use a different variable than len for the inner loop to avoid running into variable scope issues.
Related
I'm working on a problem where I need to find all the power set of a given string which are all the possible subsets. I feel like I'm close with my current code but I can't figure out why I'm getting stuck on an infinite loop for my second iteration. I ran it through the debugger but I still can't seem to figure it out even though I'm sure it's very simple. When i = 0 then it goes to the second loop where j = 0 && j < 1 so for example if help is my given str argument then I would expect it to add j + '' and push it into my allSubsets array. The problem is that the j iteration will keep looping and doing j++ and will never stop. I'm not sure why this is. One particular question even if I solve this infinite loop - do I need to update the allSubsets.length in the iteration to keep it updated with the pushed in strings?
var powerSet = function(str) {
let allSubsets = [''];
for (let i = 0; i < str.length; i++) {
debugger;
for (let j = 0; j < allSubsets.length; j++) {
allSubsets.push(sortLetters(str[i] + allSubsets[j]));
}
}
return allSubsets;
};
var sortLetters = (word => {
//convert string to an array
//use the sort to sort by letter
//convert array back to string and return
return word.split('').sort().join('');
})
Everytime you push to allSubSets, the length increases, and thus, your loop never ends. A declarative loop runs on the range of the initial loop. See below for a fix based on your code:
var powerSet = function(str) {
let allSubsets = [''];
for (let i = 0; i < str.length; i++) {
allSubsets.forEach( (_char, j) => { // declarative loop here
allSubsets.push(sortLetters(str[i] + allSubsets[j]));
})
}
return allSubsets;
};
var sortLetters = (word => {
return word.split('').sort().join('');
})
From MDN web docs:
The range of elements processed by forEach() is set before the first invocation of callback. Elements which are appended to the array after the call to forEach() begins will not be visited by callback. If existing elements of the array are changed or deleted, their value as passed to callback will be the value at the time forEach() visits them; elements that are deleted before being visited are not visited. If elements that are already visited are removed (e.g. using shift()) during the iteration, later elements will be skipped. (See this example, below.)
See the fourth paragraph under descriptions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description
i am newbie learner and i am learning basic javaScript from codecademy.I stuck at "Search Text for Your Name" tutorial 5/7.
here is my question:
your loop should stop when it hits the value of the first iterator (say, i)
plus the length of your myName variable.
here is some informations from to tutorial:
Your second "for" loop
Okay! Last loopy step: add another for loop, this time inside the body of your if statement (between the if's {}s).
This loop will make sure each character of your name gets pushed to the final array. The if statement says: "If we find the first letter of the name, start the second for loop!" This loop says: "I'm going to add characters to the array until I hit the length of the user's name." So if your name is 11 letters long, your loop should add 11 characters to hits if it ever sees the first letter of myName in text.
For your second for loop, keep the following in mind:
First, you'll want to set your second loop's iterator to start at the first one, so it picks up where that one left off. If your first loop starts with
> for(var i = 0; // rest of loop setup
your second should be something like
> for(var j = i; // rest of loop setup Second
think hard about when your loop should stop.
Finally, in the body of your loop, have your program use the .push() method of hits. Just like strings and arrays have a .length method, arrays have a .push() method that adds the thing between parentheses to the end of the array. For example,
newArray = [];
newArray.push('hello');
newArray[0]; // equals 'hello'
and here is my code:
multistr:true
var text = "Hey, how are you \
doing? My name is Emily.";
var myName = "Emily";
var hits = [];
for (var i = 0; i > text.length; i++)
{
if (text[i] === 'E')
{
for(var j = i; j > text.length; j++){
};
};
};
ps: i don't want to pass this tutorial without understand it. please help me. teach me.
for (var i = 0; i > text.length; i++) should be
for (var i = 0; i < text.length; i++)
otherwise it won't ever meet the criteria to even start the loop.
Welcome on board! You confused > with <. Your loops won't run because for the first check when i = 0 it certainly does not hold that 0 > text.length, because text.length is at least 0 (there are no strings shorter than the empty string).
You should make a habit of manually going through your loops for the first two steps and then check what happens just before the loop ends.
Here is what I got for my code:
for ( i = 0; i < text.length; i++)
{
if ( text[i] === "E")
{
for( var j = i; j < (myName.length + i ); j++)
{
hits.push(text[j]);
}
}
};
It looks like you were missing the " + i " part in your second for loop. That seems to make sure that the first loop will be included. I tried it without the "+ i" and it does not work.
I tried continuing directly from the second for loop using a "+ j" and that only crashes the browser.
I've written the functions below as part of a much larger application for processing FASTA formatted files via a web interface. For some reason it decided to run into infinity when call upon my baseCounts() function from within makePretty(). It might be worth noting that both functions are encapsulated by the same parent function.
The function baseCounts() returns valid data in the form of a 100+ long array, console.log confirms that it is not to blame so the problem has to be with makePretty().
Any help is welcome.
function baseCount(records){
// Count instances of Bases in array
var basecounts = Array();
for (i=0; i < records.length; i++){
var record = records[i];
console.log(record);
var count = [record.match(/A/g), record.match(/T/g), record.match(/C/g), record.match(/G/g)];
var basecount = Array();
for (i=0; i < count.length; i++){
basecount.push(count[i].length);
}
// return array of occurance
basecounts.push(basecount);
}
}
function makePretty(fasta){
// Make FASTA more human friendly
var data = Array();
var basecounts = Array();
var bases = Array();
console.log(fasta.length);
// Generate base array
for (i=1; i < fasta.length; i++){
bases.push(fasta[i][2])
}
basecounts = baseCount(bases); // RUNS INTO INFINITY
for (i=0; i < fasta.length; i++){
var record = Array();
record.push(i); // Add protein number
record.push(fasta[i][0]); // Add NC_#
record.push(fasta[i][1]); // Add base index
_record = fasta[i][2];
var l_record = _fasta.length; // Protein length
//var basecount = baseCount(_record);
var cg_content;
}
}
Your nested loops are using the same variable i, and clobbering each other's state.
for (i=0; i < records.length; i++){
...
for (i=0; i < count.length; i++){
...
}
Use distinct variables, say i and j or better yet pick meaningful names.
Also you should declare the variables (var i) to ensure they're local to the function.
Finally, use ++i, not i++. The former means "increment i" while the latter means "i, and oh by the way increment it". They both increment i, but the latter one returns the old value, which is a special language feature to use in special cases.
You're reseting your variable counter in your inner loop (i).
To avoid this, and future problems like it as well as hoisting issues, I would suggest using the newer functions such as forEach or map. You can also clean up your code this way:
function baseCountFunc(records){
// Count instances of Bases in array
var basecount = [];
records.forEach(function(record) {
var count = [record.match(/A/g), record.match(/T/g), record.match(/C/g), record.match(/G/g)];
count.forEach(function(countElement) {
basecount.push(countElement.length);
});
basecounts.push(basecount);
});
}
Also, I noticed you named your function the same name as your variables, you should avoid that as well.
I want to select all elements with the css class
.arrow-down
Sorry but i simply dont find the correct answer, for my problem!
I have an javascript code:
document.getElementsByClassName("arrow-down")[0].style.borderTopColor=""+blu+"";
so how do i select not the first but [all] or is there a way to [1;2;3;]??
getElementsByClassName("arrow-down")[all]
getElementsByClassName("arrow-down")[1;2...]
I tried many things but simply dont get it!
Greetings from germany!
You need to iterate over the list of returned results.
var elements = document.getElementsByClassName("arrow-down");
for (var i = 0, len = elements.length; i < len; i++){
elements[i].style.borderTopColor = blu;
}
If you want to only do a specific subset based on the index, then you can add a condition that checks the value of i. I'm also assuming that blu here is a variable you have defined somewhere?
for (var i = 0, len = elements.length; i < len; i++){
if (i === 1 || i === 2 || i === 3){
elements[i].style.borderTopColor = blu;
}
}
Unfortunately, JavaScript does not have a shorthand for accessing a specific subset of array values, or for applying changes to multiple elements at once. That is something that jQuery does automatically for you. For instance, with jQuery you could write this as:
$('.arrow-down').css('borderTopColor', blu);
document.getElementsByClassName("arrow-down") does select all of such elements.
These are returned in a node list (which can be treated as an array), which is why using [0] on that returns the first element.
Loop over the different elements that the expression returns and act on them:
var elements = document.getElementsByClassName("arrow-down");
var elementsNum = elements.length)
for(var i = 0; i < elementsNum; i++)
{
var anElement = elements[i];
// do something with anElement
}
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);
}