javascript loop only applying to every other element - asp.net

i have the following javascript below after i finish an ajax query
all of my images have name="pic"
<script type="text/javascript">
function done() {
var e = document.getElementsByName("pic");
alert(e.length);
for (var i = 0; i < e.length; i++) {
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}
}
my goal is to apply an image border around using this library:
http://www.netzgesta.de/instant/
the problem is that for some reason this works but it only seem to apply to every other picture instead of every one. any clue why the code above would skip every other element??
EDIT: I added an alert in the loop and it does correctly go 0, 1,2,3,4,5,6 . .
for (var i = 0; i < e.length; i++)
{
alert(i);
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}

it only seem to apply to every other picture instead of every one
That's a classic sign of destructive iteration.
Consider what happens if, as I'm guessing, the function cvi_instant.add replaces the element named pic with some other element or elements.
getElementsByName returns a ‘live’ NodeList: it is kept up to date every time you make a change to the DOM. So if it had five elements before, after your call to cvi_instant.add it now contains only four: the first node is gone and nodes 1–4 have moved down to positions 0–3.
Now you go around the loop again. i++, so we're looking at element 1. But element 1 is now what was originally element 2! We skipped the original element 1, and we will continue skipping every other element until we reach the end of the (now half as long) list.
Altering a list at the same time as iterating it causes this kind of problem. If the process inside the iteration actually adds elements to the list you can even get an infinite loop!
The quick fix is to iterate the loop backwards. Now you do the last element first, leaving all the other elements in their original positions and causing no skipping:
var e= document.getElementsByName("pic");
for (var i= e.length; i-->0;) {
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}
Another simple solution if you know you're always going to be removing the element from the list on each call is:
var e= document.getElementsByName("pic");
while (e.length>0) {
cvi_instant.add(e[0], { shadow: 75, shade: 10 });
}
The most general solution is needed when your loop body can do anything to the list, such as inserting new elements named pic at the start of the document or removing other elements from the middle. It is slightly slower but always safe to make a static copy of the list to work from:
function Array_fromList(l) {
var a= [];
for (var i= 0; i<l.length; i++)
a.push(l[i]);
return a;
}
var e= Array_fromList(document.getElementsByName("pic"));
for (var i= 0; i<e.length; i++) {
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}

My guess is that cvi_instant.add() is doing some incrementing or iteration on the values passed to it. Try doing this instead - it's easier, and I believe it will fix your problem:
function done() {
var e = document.getElementsByName('pic');
for (pic in e) { cvs_instant.add(pic, { shadow: 75, shade: 10 }); }
}

Hi I came across the same problem.
My script was skipping every other
element. I finally solved it by simply
changing the variable name from i to
k in my loop. My guess is therefor
that the variable i is used by
getElementsByTagName internally to
keep track of where it is in the
live nodelist and is leaking out
to the programmers interface somehow.
So its a bug! :-)

-- EDIT:
All of what I claim below appears to be totally wrong. I leave this here as a point for anyone who thought the same :) I tested in FF3. I would love to claim that I saw this behaviour once, in IE, but maybe it was many years ago (come to think of it, it was probably 7 years ago). My memory is probably bad :)
-- OLD:
To slightly expand on my wild guess, if it turns out to be accurate:
From memory, if you don't declare a variable ('var ...') it'll use one from somewhere else.
Thus, without testing, this code:
for(var k = 0; k < 2; k++){
f();
alert("k: " + k);
}
function f () {
k++;
}
Should show the same behaviour. I think TML's solution is quite nice, from a 'defensive coding' point of view, it my analysis turns out to be correct.

Related

Finding the row of an object

I'm trying to create a procedural shape made up of quads.
I want to be able to take any quad and use it's index to find the row that it is in.
Take quad 9 from the image. What sort of function can I use to find the row (in this case it is 2 from a 0-index). What about quad 20?
The rows always change in width by 2 quads, one removed from each side.
Sorry it's a bit convoluted but I'm not sure how to approach the problem.
Assume diameter d and quad number q. I claim the rows go 0 to d-1. Moreover, there are (d/2)(2+d) elements. The easier case is if 0<=q<(d/4)(2+d) in which case we are in the first half. Then the index is trunc((-1+sqrt(1+4*q))/2). This comes from using the observation that row n begins with n(n+1) which could be formally shown with the sum of an arithmetic series, then working backwards and solving the quadratic equation.
On the other hand, if we are in the second half (d/4)(2+d)<=q<(d/2)(2*d) and we solve by taking the offset from the end. Let q' be (d/2)(2+d)-1-q. Apply the above index formula to q' instead of q, and subtract the result from d-1 to get the index of q's row.
I may be off by one here or there, but I think this is the gist of it.
I was thinking since this was posted to a programming site, maybe it would be more logical to give a function one could implement without pulling out a lot of math, and instead just relying on addition. I think it would be easier to follow and harder to mess up (though maybe I underestimate my capability to mess up, and I almost did).
var quadRowIndex = function (diameter, quadNumber) {
//diameter should be a positive even number
//quadNumber should be between 0 and index of last number in last row (inclusive)
var quadIndex = 0; //holds the RowIndex, which the function will return once the row contains quadNumber
var rowStartNum = 0;
var rowLength = 2;
//iterate through first half
while (rowLength <= diameter) {
rowStartNum += rowLength;
if (rowStartNum > quadNumber) {
return quadIndex;
}
quadIndex++;
rowLength += 2;
}
rowLength -= 2;
//iterate through second half if still here
while (rowLength >= 2) {
rowStartNum += rowLength;
if (rowStartNum > quadNumber) {
return quadIndex;
}
quadIndex++;
rowLength -= 2;
}
//still here -- number was too high, return error signal
return -1;
};
console.log(quadRowIndex(6, 9));
console.log(quadRowIndex(6, 20));
console.log(quadRowIndex(6, 100));

How to suitably avoid RangeErrors when "looking around" this 2D array?

I have a 2D array structure to represent a grid of tiles that is a part of the game I am making. One aspect of the game is that the grid is filled in in a somewhat random fashion, based on analysis of a text file. Right from the outset though, I already realised that just leaving it be pretty much randomly done like this without sticking in some kind of validity checks or prevention mechanism, to stop really badly configured grid from forming, would not work out. The main problem I want to avoid is too many tiles that would be untraversable being close together, potentially severing chunks of the grid from the rest.
The idea I came up with to try avoid some really bad grids is to check when assigning a tile value to each "grid square" during generation with logic like this
if (tileBeingInserted.isTraversable()) {
//all is well
return true;
} else {
//we may have a problem, are there too many untraversables nearby?
//Proceed to check all squares "around" the current one.
}
To be clear, checking around the current square means checking the square immediately adjacent in each of the 8 cardinal directions. Now, my problem is that I am trying to reason out how to code this so that it will certainly not give a RangeErrorat any point or at least catch it and recover if it must. As an example, you could clearly take one of the corner squares to be the worst scenario in the sense that only 2 of the squares the algorithm would want to check are within the array's bounds. Naturally, if a RangeErrorhappens for this reason I just want the program to progress onward without issue so the structure
try {
//check1
//check2...8
} catch (RangeError e) {
}
is unacceptable because as soon as a single out of range square is tested the code falls out of the check block. An alternative I thought of, but do not like because of its messiness, would be to individually wrap each check in a try-catch and yes that would work I guess but that's some horrid looking code...so can anyone help me out here? Is there perhaps a different angle from which to come at this problem of avoiding the RangeErrors that I am not seeing?
So my code for testing whether another untraversable tile should be placed has shaped up like this:
bool _tileFitsWell(int tileTypeInt, int row, int col)
{
//...initialise some things, set stuff up
...
if (tile.traversable == true) {
//In this case a new traversable tile is being put in, so no problems.
return true;
} else {
//begin testing what tiles are around the current tile
//Test NW adjacent
if (row > 0 && col > 0) {
temp = tileAt(row - 1, col - 1);
if (!temp.traversable) {
strikeCount++;
}
}
//Test N adjacent
if (row > 0) {
temp = tileAt(row - 1, col - 1);
if (!temp.traversable) {
strikeCount++;
}
}
//Test NE adjacent
if (row > 0 && col < _grid[0].length - 2) {
temp = tileAt(row - 1, col 1);
if (!temp.traversable) {
strikeCount++;
}
}
//Test W adjacent
if (col > 0) {
temp = tileAt(row, col - 1);
if (!temp.traversable) {
strikeCount++;
}
}
}
return strikeCount < 2;
}
The code inside each "initial" if-statement (the ones that check row and col) is a bit pseudocode-ish for simplicity's sake. As I explained in a previous comment, the reason why I don't need to check tiles in the other 4 cardinal directions is since these checks are done while filling the map, tiles in those positions will always be either uninitialised or just out of bounds, depending on what tile the function is called to check at a given time.

Checking number of times CSS classes called. [duplicate]

This question already has answers here:
How to identify unused CSS definitions from multiple CSS files in a project
(3 answers)
Closed 9 years ago.
I was thinking of writing a script which would tell me:
How often each CSS class defined in my .css file is used in my code
Redundant CSS classes - classes never used
CSS classes hat are referenced that don't exist.
But I just want to make sure something like this doesn't exist already? Does it?
Thanks
Just for fun, I wrote one.
try it
First we need to find our style sheet. In an actual script, this would be written better, but this works on jsFiddle.
var styles = document.head.getElementsByTagName('style');
var css = styles[styles.length - 1].innerHTML;
Then remove comments, and the bodies of each selector (i.e. the stuff between the brackets). This is done because there could be a .com in a background-image property, or any number of other problems. We assume there isn't a } in a literal string, so that would cause problems.
var clean = css.replace(/\/\*.*?\*\//g, '').replace(/\{[^}]*\}/g, ',');
We can find classes with regular expressions, and then count how many of them occur.
var re_class = /\.(\w+)/g;
var cssClasses = {}, match, c;
while (match = re_class.exec(clean)) {
c = match[1];
cssClasses[c] = cssClasses[c] + 1 || 1;
}
I used jsprint for displaying our findings. This shows how many times each class is mentioned in our CSS.
jsprint("css classes used", cssClasses);
Thanks to Google and this answer we can find all elements in the body, and loop through them. By default, we assume no classes were used in our HTML, and all classes used were defined.
var elements = document.body.getElementsByTagName("*");
var neverUsed = Object.keys(cssClasses);
var neverDefined = [];
var htmlClasses = {};
We get each elements class, and split it on the spaces.
for (var i=0; i<elements.length; i++) {
var e = elements[i];
var classes = (e.className || "").split(" ");
This is a three dimensional loop, but it works nicely.
for (var j=0; j<classes.length; j++) {
for (var k=0; k<neverUsed.length; k++) {
We thought classes[j] was never used, but we found a use of it. Remove it from the array.
if (neverUsed[k] === classes[j]) {
neverUsed.splice(k, 1);
}
}
It looks like we found a class that doesn't appear in our CSS. We just need to make sure it's not an empty string, and then push it onto our array.
if (classes[j].length && cssClasses[classes[j]] == null) {
neverDefined.push(classes[j]);
}
Also count the number of times each class is used in HTML.
if (classes[j].length) {
htmlClasses[classes[j]] = htmlClasses[classes[j]] + 1 || 1;
}
}
}
Then display our results.
jsprint("html class usage", htmlClasses);
jsprint("never used in HTML", neverUsed);
jsprint("never defined in CSS", neverDefined);

Implementing an IObservable to compute digits of Pi

This is an academic exercise, I'm new to Reactive Extensions and trying to get my head around the technology. I set myself a goal of making an IObservable that returns successive digits of Pi (I happen to be really interested in Pi right at the moment for unrelated reasons). Reactive Extensions contains operators for making observables, the guidance they give is that you should "almost never need to create your own IObsevable". But I can't see how I can do this with the ready-made operators and methods. Let me elucidate a bit more.
I was planning to use an algorithm that would involve the expansion of a Taylor series for Arctan. To get the next digit of Pi, I'd expand a few more terms in the series.
So I need the series expansion going on asynchronously, occasionally throwing out the next computed digit to the IObserver. I obviosly don't want to restart the computation from scratch for each new digit.
Is there a way to implement this behaviour using RX's built-in operators, or am I going to have to code an IObservable from scratch? What strategy suggests itself?
For something like this, the simplest method would be to use a Subject. Subject is both an IObservable and IObserver, which sounds a bit strange but it allows you to use them like this:
class PiCalculator
{
private readonly Subject<int> resultStream = new Subject<int>();
public IObservable<int> ResultStream
{
get { return resultStream; }
}
public void Start()
{
// Whatever the algorithm actually is
for (int i = 0; i < 1000; i++)
{
resultStream.OnNext(i);
}
}
}
So inside your algorithm, you just call OnNext on the subject whenever you want to produce the next value.
Then to use it, you just need something like:
var piCalculator = new PiCalculator();
piCalculator.ResultStream.Subscribe(n => Console.WriteLine((n)));
piCalculator.Start();
Simplest way is to create an Enumerable and then convert it:
IEnumerable<int> Pi()
{
// algorithm here
for (int i = 0; i < 1000; i++)
{
yield return i;
}
}
Usage (for a cold observable, that is every new 'subscription' starts creating Pi from scratch):
var cold = Pi().ToObservable(Scheduler.ThreadPool);
cold.Take(5).Subscribe(Console.WriteLine);
If you want to make it hot (everyone shares the same underlying calculation), you can just do this:
var hot = cold.Publish().RefCount();
Which will start the calculation after the first subscriber, and stop it when they all disconnect. Here's a simple test:
hot.Subscribe(p => Console.WriteLine("hot1: " + p));
Thread.Sleep(5);
hot.Subscribe(p => Console.WriteLine("hot2: " + p));
Which should show hot1 printing only for a little while, then hot2 joining in after a short wait but printing the same numbers. If this was done with cold, the two subscriptions would each start from 0.

Using Count To Split A Checklist Into 2 Columns in X++ Fetch Method

Here is what I have so far, this is returning two columns, but each counter is stopping and then duplicating the same value over and over...
if(lLogisticsControlTable.APMJobTypeId)
select count (RecID) from jobTypeCheck where jobTypeCheck.APMJobTypeId == lLogisticsControlTable.APMJobTypeId;
{
counter = jobTypeCheck.RecId;
}
while select jobTypeCheck where jobTypeCheck.APMJobTypeId == lLogisticsControlTable.APMJobTypeId
{
counter1 = counter / 2;
halfCount1 = counter - counter1;
if(halfcount <= counter1)
{
halfCount++;
jobListCheck1 = jobTypeCheck.Name;
}
if (halfCount1 > halfCount)
{
halfCount1++;
jobListCheck2 = jobTypeCheck.Name;
}
element.execute(2);
}
}
As Michael Brown indicated, it's difficult to understand the problem with half of the code ;)
However, I would suggest that you call the element.execute(2) method on every second pass through the loop? That way jobListCheck1 would be on the left, and jobListCheck2 would be on the right hand side. Finally you would then need to check immediately outside of your loop if you had an odd number of jobTypeCheck elements, and call the element.execute(2) method one last time remembering to set the jobListCheck2 variable as empty beforehand.
Regards

Resources