Help modifying recursive function - asp.net
Given a canvas, let's say 10x10, and given 3 rectangles/squares.
Canvas = 10x10
Rectangle 1 = 2x2
Rectangle 2 = 3x3
Rectangle 3 = 2x4
I've created a recursive function that loops every position of every rectangle on the canvas, and it works fine. (I've included the function below incase anyone wants to see it but I don't think it's necessary).
We can see that rectangle 1 and 2 are non rotatable, IE, if you rotate either of them 90 degrees essentially they are the same shape. However rectangle 3 is rotatable.
How do I change/construct the loop/recurisve function so that it loops every position of every rectangle, along with every possible rotation?
The aim is to loop through every possible fitting of the shapes on the canvas.
Thanks for any help!
Sub recurse(ByVal startPoint As Integer)
Dim x As Integer
Dim y As Integer
Dim validSolution As Boolean = isSolutionValid()
Dim loopXTo As Integer
Dim loopYTo As Integer
Dim solutionRating As Integer
'If parent nodes create invalid solution, we can skip (375 iterations from 1,600 iterations saving)
If validSolution = True Then
If (startPoint = 0) Then
loopXTo = Math.Floor((canvasCols - squareObjects(startPoint).sqRows()) / 2) '576 iterations from 1,680 iterations
loopYTo = Math.Floor((canvasRows - squareObjects(startPoint).sqCols) / 2) '31,104 iterations from 90,720 iterations
Else
loopXTo = canvasCols - squareObjects(startPoint).sqRows
loopYTo = canvasRows - squareObjects(startPoint).sqCols
End If
'Loop all positions on canvas
For x = 0 To loopXTo
For y = 0 To loopYTo
'Set coords of square
squareObjects(startPoint).setSquareCords(x, y)
'Phyiscally place it in canvas
placeSquareOnCanvas(x, y, squareObjects(startPoint).sqRows, squareObjects(startPoint).sqCols)
'Recursive, get next square
If (startPoint + 1 < totalSquares) Then
recurse(startPoint + 1)
Else
validSolution = isSolutionValid()
'Is solution valud
If (validSolution = True) Then
solutions = solutions + 1
End If
iterations = iterations + 1
'Response.Write("<br /><b>Iteration " & iterations & "</b>")
If (validSolution) Then
'Rate solution, record if best
solutionRating = rateSolution()
If solutionRating > bestCellSaving Then
bestCellSaving = solutionRating
copySolution()
End If
'Response.Write(" <span style='color:green'> <B>VALID SOLUTION</B></span> (" & rateSolution() & ")")
End If
'printCanvas(canvas)
End If
squareObjects(startPoint).removeSquare(canvas)
Next
Next
End If
End Sub
If you extract the loops in a separate routine the solution emerges relatively easily.
I have changed the validSolution logic a bit to make the code shorter - now we don't call recurse if the solution is invalid and we don't need to check for isSolutionValid() at the beginning of recurse(). These changes make counting the iterations harder so I removed that code, but it should be possible to add it later.
The recurse() routine without the last "If" statement should behave exactly as your code. The last "If" statement essentially performs the loops for a rotated rectangle.
I am not sure how removeSquare() is implemented, but it may need to know the orientation to be able to work correctly.
Sub recurse(ByVal startPoint As Integer)
Dim loopXTo As Integer
Dim loopYTo As Integer
If (startPoint = 0) Then
loopXTo = Math.Floor((canvasCols - squareObjects(startPoint).sqRows) / 2)
loopYTo = Math.Floor((canvasRows - squareObjects(startPoint).sqCols) / 2)
Else
loopXTo = canvasCols - squareObjects(startPoint).sqRows
loopYTo = canvasRows - squareObjects(startPoint).sqCols
End If
fitSqare(loopXTo, loopYTo, False)
If (squareObjects(startPoint).sqCols <> squareObjects(startPoint).sqRows) Then
fitSqare(loopYTo, loopXTo, True)
End If
End Sub
Sub fitSquare(ByVal loopXTo As Integer, ByVal loopYTo As Integer, ByVal rotate As Boolean)
Dim x As Integer
Dim y As Integer
Dim solutionRating As Integer
Dim validSolution As Boolean
'Loop all positions on canvas
For x = 0 To loopXTo
For y = 0 To loopYTo
'Set coords of square
squareObjects(startPoint).setSquareCords(x, y)
'Phyiscally place it in canvas
If (rotate) Then
placeSquareOnCanvas(x, y, squareObjects(startPoint).sqCols, squareObjects(startPoint).sqRows)
Else
placeSquareOnCanvas(x, y, squareObjects(startPoint).sqRows, squareObjects(startPoint).sqCols)
End If
validSolution = isSolutionValid()
'Is solution valud
If (validSolution) Then
'Recursive, get next square
If (startPoint + 1 < totalSquares) Then
recurse(startPoint + 1)
Else
solutions = solutions + 1
'Rate solution, record if best
solutionRating = rateSolution()
If solutionRating > bestCellSaving Then
bestCellSaving = solutionRating
copySolution()
End If
End If
End If
squareObjects(startPoint).removeSquare(canvas) 'removeSquare may require additional work to handle rotated state
Next
Next
End Sub
If the canvas is always a square then you don't need to change much. The result for the rotated rectangle 3 is the same as for the unrotated, except the origin of the Canvas is different. Imagine leaving the Rectangle 3 unrotated and rotating the canvas 90 degrees in the other direction. This means that you should be able to use some maths on the same results to get your answer.
Put your (x,y) coordinate loop in its own function. Then call the (x,y) coordinate loop on a rectangle of WxH, and then call it again on the rotated rectangle HxW.
Alternatively you can put the branching on the two rotations of your rectangle inside the (x,y) loop, after both coordinates have been picked, but before you make the recursive call.
In both cases you will need to be careful about whether your rotation causes the rectangle to exceed the height or width of your bounding box.
Can't you simply scan the list of shapes and for those that are rectangles (SizeX != SizeY) add a cloned rectangle with { SizeX = source.SizeY, SizeY = source.SizeX } (eg.: rotated rectangle)?
That would of course mean to do the loops twice (one for the unrotated list of shapes and one for the rotated one).
=> doing something like
squareObjects(startPoint) = squareObjects(startPoint).Rotate();
recurse(startPoint);
Frankly I don't think your implementation is the best- but if you don't want to make big changes and make separate routines you can just put the code for the rectangles twice in the same function-iteration.
So after:
'Phyiscally place it in canvas
placeSquareOnCanvas(x, y, squareObjects(startPoint).sqRows, squareObjects(startPoint).sqCols)
[......]
End If
squareObjects(startPoint).removeSquare(canvas)
You can do a check
IF the square is rectangle (width <> height)
then copy the same code again (in Then code) changing sqRows with sqCols in placeSquareOnCanvas().
The recursion will not be anymore linear, as this will make 2 recursive branches for each rectangle. Maybe it is not very nice written copying the same code 2 times, but the result will be right, the code changing is minimal and this straight solution based on your code will have more performance than trying other tweaks.
Related
Handle previous state in continuous rotation
Hello i have the following lua code which functionality is to rotate a point creating a circle. The problem I'm having is with initial and/or last state. Since there is a clock running whenever i stop the rotation and start again, the point jumps around. I tried saving the last value after the lfo is turned off, and then use this value in each sin and cos functions but i cannot make it work well. Thank you! The Code: local last = 0 local trigger = false function update() t = getMillis() T = 3000 if trigger == true then x = math.cos(2*math.pi*( (t - last) + t) /T) y = math.sin(2*math.pi*( (t - last) + t) /T) end end function onValueChanged(key) if key == "x" and self.values.x == 1 then if trigger == true then last = t end trigger = not trigger end end
Lua Love2d Quadtree recursion
UPDATE -- I figured it out. Turns out I am bad at math and visualizing 2d points. I wasn't setting south or east subdivisions correctly. I have been trying to make a quadtree to track points in Love2d. I have the most of the code written, but I don't think the recursion is working properly. I'm pretty new to the coding scene, so I really don't know where to start. It seems to leave out points that go into the southeast quadrant. I think as it goes recursively into the insert function it either looks at the parents point array or doesn't seem to go into all the insert functions. local QuadTree = {} QuadTree.__index = QuadTree function QuadTree:new(boundary,capacity) local quadTemp = {} setmetatable(quadTemp, QuadTree) if (not boundary) then print('No boundary given to new QuadTree') end if (type(capacity) ~= 'number') then print('Boundary should be a number') end if (capacity < 1) then print('capacity should be greater than one') end quadTemp.boundary = boundary quadTemp.capacity = capacity quadTemp.points = {} quadTemp.hasDivided = false return quadTemp end function QuadTree:insert(p) --If this point doesnt belong in this spot dont add it if (not self.boundary:contains(p)) then return false elseif (#self.points<self.capacity) then table.insert(self.points,p) return true elseif(not self.hasDivided) then self:subdivide() elseif(self.hasDivided) then return self.northeast:insert(p) or self.northwest:insert(p) or self.southeast:insert(p) or self.southwest:insert(p) end end function QuadTree:subdivide() local x = self.boundary.xpos local y = self.boundary.ypos local w = self.boundary.width / 2 local h = self.boundary.height / 2 local nw = Rectangle:new(x,y,w,h) self.northwest = QuadTree:new(nw,self.capacity) local ne = Rectangle:new(w,y,w,h) self.northeast = QuadTree:new(ne,self.capacity) local sw = Rectangle:new(x,h,w,h) self.southwest = QuadTree:new(sw,self.capacity) local se = Rectangle:new(w,h,w,h) self.southeast = QuadTree:new(se,self.capacity) self.hasDivided = true end function QuadTree:query(range,found) --If we havent found any yet lets create a list incase we do if (not found) then found = {} end --If this cell doesnt contain the boundary then return an empty list if (not range:intersects(self.boundary)) then return found end for k,v in pairs(self.points) do if (range:contains(v)) then table.insert(found,v) end end --If the current cell has divided we need to check its children if (self.hasDivided) then self.northwest:query(range,found) self.northeast:query(range,found) self.southwest:query(range,found) self.southeast:query(range,found) end return found; end
Axis label values are generated dynamic, however require specific labels to be displayed
I am trying to dynamically generate axis label values as follows. Dim dt As DataTable dt = ds.Tables(0) Dim y2max As Double = dt.Compute("max(return)", String.Empty) + 0.001 Dim y2min As Double = dt.Compute("min(return)", String.Empty) - 0.001 Dim ymax As Double = dt.Compute("max(TC_" & TC & ")", String.Empty) + 0.005 Dim ymin As Double = dt.Compute("min(TC_" & TC & ")", String.Empty) - 0.005 And generate the following chart. http://i.imgur.com/LrfsvDT.png I am able to achieve desired scaling with this approach , however i want by PRIMARY Y label values to have "1". Can i set an appropriate interval or format Y label values to achieve this. This is what i wish to achieve http://i.imgur.com/HKCrLmw.png I am not concerned about the interval values/length, however i need my Blue line series to start with 1.
WRONG ANSWER: I think you are looking for the AxisY.IntervalOffset property. Why is it wrong? Because it shifts the labels. It just happened that it looked right in my previous attempt. RIGHT ANSWER: If you set the AxisY.Crossing property to 1 then it will force it to use 1 as a label value, and calculate the other labels appropriately. You then need to set AxisY.IsStartedFromZero = False to avoid zero being included on the axis and AxisX.IsMarksNextToAxis = False to make the x-axis labels appear at the bottom edge of the chart. So... Sub GenerateChart() Chart1.Legends.Clear() Chart1.Series.Clear() ' generate some sample data Dim s1 As New Series For i = 0 To 180 Step 2 s1.Points.AddXY(i, Math.Sin(Math.PI * i / 60) * 0.004 + 1) Next Chart1.Series.Add(s1) Chart1.Series(0).ChartType = SeriesChartType.Line Chart1.Series(0).BorderWidth = 2 Chart1.ChartAreas(0).AxisY.IsStartedFromZero = False Chart1.ChartAreas(0).AxisY.Crossing = 1 Chart1.ChartAreas(0).AxisX.IsMarksNextToAxis = False ' avoid the label "1.000" being formatted as "1" Dim labelFormat = "0.000" Chart1.ChartAreas(0).AxisY.LabelStyle = New LabelStyle With {.Format = labelFormat} End Sub Gives
VB: how to get the index(es) of an array element if used in For Each
i have the following VB Script written in an .asp file Dim myArr(5, 6) '// a 6 * 7 array For i = LBound(myArr, 1) to UBound(myArr, 1) For j = LBound(myArr, 1) to UBound(myArr, 1) myArr(i, j) = "i:" & i & ", j:" & j next next Dim i i = 0 For Each k In myArr Response.Write("i:" & i ", k:" & k & "<br>") i = i + 1 Next using For Each i can iterate through all the array items, and the question is how can i get the index for each dimension ? for example: how can i get k index after 10th loop that is 2 and 4 ?
Useful info number 1 First of consider this bit of VBS: Option Explicit Dim aaa(1,1,1) Dim s : s = "" Dim i, j, k For i = LBound(aaa, 3) To UBound(aaa, 3) For j = LBound(aaa, 2) To UBound(aaa, 2) For k = LBound(aaa, 1) To UBound(aaa, 1) aaa(k, j, i) = 4 * i + 2 * j + k Next Next Next Dim x For Each x in aaa s = s + CStr(x) + " : " Next MsgBox s This returns "0 : 1 : 2 : 3 : 4 : 5 : 6 : 7 :" which looks good, but note the order of indexers in the inner assignment aaa(k, j, i). If we were to use the more natural aaa(i, j, k) we'd see what appears to us to be a jubbled order returned. Thats because we assume that the left most indexer is the most significant but it isn't its the least significant. Where bounds start at 0 then for the first dimension all the values in index 0..N are held contigiously where the other dimensions are 0. Then with the next dimension at 1, the next set of 0..N members of the first dimension follow and so on. Useful info number 2 Given an array of unknown number of dimensions the following code returns the count of dimensions: Function GetNumberOfDimensions(arr) On Error Resume Next Dim i For i = 1 To 60000 LBound arr, i If Err.Number <> 0 Then GetNumberOfDimensions = i - 1 Exit For End If Next End Function Solution Given an array construct like this. Dim arr(3,3,3) Dim s : s = "" Dim i, j, k For i = LBound(arr, 3) To UBound(arr, 3) For j = LBound(arr, 2) To UBound(arr, 2) For k = LBound(arr, 1) To UBound(arr, 1) arr(k, j, i) = 16 * i + 4 * j + k Next Next Next Here is some code that is able to determine the set of indices for each item in an array of arbitary dimensions and sizes. Dim dimCount : dimCount = GetNumberOfDimensions(arr) Redim dimSizes(dimCount - 1) For i = 1 To dimCount dimSizes(i - 1) = UBound(arr, i) - LBound(arr, i) + 1 Next Dim index : index = 0 Dim item For Each item in arr s = "(" Dim indexValue, dimIndex indexValue = index For dimIndex = 0 To dimCount - 1 s = s + CStr((indexValue mod dimSizes(dimIndex)) - LBound(arr, dimIndex + 1)) + ", " indexValue = indexValue \ dimSizes(dimIndex) Next Response.Write Left(s, Len(s) - 2) + ") = " + Cstr(item) + "<br />" index = index + 1 Next An interesting acedemic exercise, not sure how useful it is.
You can't. For each is defined to iterate over objects without having to know the amount of objects (as defined in the IEnumerable interface) at the moment the next object is returned (making multithreading possible). It is also not specified that you'll receive your objects in exact the same order as you put them (although, I never experienced an other order for arrays), that depends on the Enumerator Interface object that is specified for the collection. Fortunately, there are other tricks to do what you want, but the implementation depends on the problem you are trying to solve. For example, you can use an array with arrays, the ArrayList class from System.Collections.ArrayList or create an own class where you store your values or objects. Please note: There are some discussions about this correctness of this answer, see the comments below. I'll study the subject and will share any relevant experiences I got from them.
You could create a helper object like this: Option Explicit dim myArr(5,6) dim i, j, k For i = LBound(myArr, 1) to UBound(myArr, 1) For j = LBound(myArr, 2) to UBound(myArr, 2) Set myArr(i, j) = [new LookupObject]("i:" & i & ", j:" & j, i, j) next next For Each k In myArr Response.Write("This is k:" & k & "<br>") Response.Write("i index of k: " & k.I & "<br>") Response.Write("j index of k: " & k.J & "<br>") Next Public Function [new LookupObject](value, i, j) Set [new LookupObject] = (new cls_LookupObject).Init(value, i, j) End Function Class cls_LookupObject Private value_, i_, j_ Public Function Init(value, i, j) i_ = i j_ = j value_ = value Set Init = me End Function Public Default Property Get Value() Value = value_ End Property Public Property Get I() I = i_ End Property Public Property Get J() J = j_ End Property End Class DISCLAIMER: As I created this code on a non Windows machine, I couldn't test it. You could find some syntax or design errors. The naming is not very great, but this way it sticks more to your concept. Although, it seems you are searching for a simple solution. Not one that will introduce more 'challenges': When you want to pass around values in the array that keep their internal indices, you need to Set them instead of just assigning them: this decreases portability. And when you use objects, you need to know how Object References work in contrast to primitives, otherwise you'll get some unexpected behavior of values changing when you don't expected it.
UPDATED If a person interested in how VBScript compares to other languages with regard to arrays, foreach looping, and especially obtaining information about the position of the element delivered by "For Each" in the collection looped over, would pose a question like: How does VBScript compare to other languages with regard to arrays, foreach looping, and especially obtaining information about the position of the element delivered by "For Each" in the collection looped over? then a short answer would have been available long ago: A foreach loop construct can deliver a pointer (memory address) - as e.g. C/C++ does; then you have to de-reference the pointer to get at the element which you can even change; positional info is optainable by pointer arithmetic) a reference (alias) (as e.g. Perl does; that allows modification, but obviously no computing of positions (unless the element accidentially contains such info)) a copy (as e.g. Python or VBScript do; neither modification nor retrieval of meta info is possible (unless some kind and clever souls like AutomatedChaos or AnthonyWJones work their heart out to implement a C/C++ alike solution by submitting a loop variable to DIVs and MODs resp. to design a class that allows to augment the plain/essential data values with meta info) You may safely ignore the rest of my answer; I just don't want to delete the following text which provides some context for the discussion. The problem can't be dealt with, until (1) armen describes the context of the real world problem in real world terms - where do the arrays come from, how many dimensions are possible, what determines the dimensional structure (row/column/...), which operations must be done in the For Each loop, why/how are the indices important for these operations (2) all contributors get their selectors for the dimensions right: For i = LBound(myArr, 1) to UBound(myArr, 1) For j = LBound(myArr, 1) to UBound(myArr, 1) or variations thereof are obviously wrong/misleading. Without replacing the 1 in one line by 2, it's not clear, what row/column-structure the code is meant for. To prove that I'm willing to contribute in a more constructive way, I throw in a function to get the (number of) dimensions for an arbitrary array: Function getDimensions(aVBS) Dim d : d = 0 If IsArray(aVBS) Then For d = 1 To 60 On Error Resume Next UBound aVBS, d + 1 If Err.Number Then Exit For On Error GoTo 0 Next End If getDimensions = d End Function ' getDimensions (based on code by M. Harris and info from the VBScript Docs) Update: Still not a solution, but some food for thought As armen (upto now) didn't provide the real story of his problem, I try to give you a fictonal one (to put a context to the rows and columns and whatever you may call the thingies in the third dimension): Let's say there is a school - Hogmond - teaching magical programming. VBScript is easy (but in the doghouse), so there are just three tests and students are admitted mid term (every penny counts). JScript is harder, so you have to do the full course and additional tests may be sheduled during the term, if pupils prove thick. F# is more complicated, so each test has to be judged in terms of multiple criteria, some of which may be be agreed upon during the term (the teachers are still learning). C# is such a 'good' language, that there is just one test. So at the end of the term the principal - Mr. Bill 'Sauron' Stumblegates - has an .xls, containing a sheet: (Doreen was accepted during the last week of the term) and a sheet: (for your peace of mind, 120 additional tests are hidden); the F# results are kept in a .txt file: # Results of the F# tests # 2 (fixed) students, 3 (fixed) test, # 4>5 (dynamic) criteria for each test Students Ann Bill Test TA TB TC TA TB TC Criteria CA 1 2 3 4 5 6 CB 7 8 9 10 11 12 CC 13 14 15 16 17 18 CD 19 20 21 22 23 24 # CE 25 26 27 28 29 30 (because I know nothing about handling three+-dimensional data in Excel). Now we have a context to think about data: it's important that Mary scored 9 for the eval test, but whether that info is stored in row 5 or 96 is not an inherent property of the data [Implies that you should think twice before you embark on the (taken by itself: impressive) idea of AutomatedChaos to create objects that combine (essential) data and (accidential) info about positions in a (n arbitrary) structure.] processing: some computations - especially those that involve the whole dataset - can be done with no regard to rows or colums (e.g. average of all scores); some may even require a restructuring/reordering (e.g. median of all scores); many computations - all that involve selection/grouping/subsets of the data - just can't be done without intimate knowledge about the positions of the data items. armen, however, may not be interested in processing at all - perhaps all he needs the indices for is to identify the elements while displaying them. [So it's futile to speculate about questions like "Shouldn't Excel/the database do the processing?", "Will the reader be content with 'D5: 9' or does he whish to see 'Mary/eval: 9' - and would such info be a better candidate for AutomatedChaos' class?", "What good is a general 'For Each' based function/sub that handles arrays of every dimension, if assignments - a(i)=, b(i,j)=, c(i,j,k)= ... - can't be parameterized?"] structure/layout: the choice of how you put your data into rows and columns is determined by convenience (vertical scrolling perfered), practical considerations (append new data 'at the end'), and technical reasons (VBScript's 'ReDim Preserve' can grow (dynamic) arrays in the last dimension only) - so for each layout that makes sense for a given context/task there are many other structures that are better in other circumstances (or even the first context). Certainly there is no 'natural order of indexers'. Now most programmers love writing/written code more than reading stories (and some more than to think about/plan/design code), so here is just one example to show what different beasts (arrays, 'iterators') our pipe dream/magical one-fits-all-dimensions 'For Each' strategy has to cope with: Given two functions that let you cut data from Excel sheets: Function getXlsRange(sSheet, sRange) Dim oX : Set oX = CreateObject("Excel.Application") Dim oW : Set oW = oX.Workbooks.Open(resolvePath("..\data\hogmond.xls")) getXlsRange = oW.Sheets(sSheet).Range(sRange).Value oW.Close oX.Quit End Function ' getXlsRange Function getAdoRows(sSQL) Dim oX : Set oX = CreateObject("ADODB.Connection") oX.open Join(Array( _ "Provider=Microsoft.Jet.OLEDB.4.0" _ , "Data Source=" & resolvePath("..\data\hogmond.xls") _ , "Extended Properties=""" _ & Join(Array( _ "Excel 8.0" _ , "HDR=No" _ , "IMEX=1" _ ), ";" ) _ & """" _ ), ";") getAdoRows = oX.Execute(sSQL).GetRows() oX.Close End Function ' getAdoRows (roll your own resolvePath() function or hard code the file spec) and a display Sub (that uses armen's very good idea to introduce a loop counter variable): Sub showAFE(sTitle, aX) Dim i, e WScript.Echo "For Each:", sTitle WScript.Echo "type:", VarType(aX), TypeName(aX) WScript.Echo "dims:", getDimensions(aX) WScript.Echo "lb :", LBound(aX, 1), LBound(aX, 2) WScript.Echo "ub :", UBound(aX, 1), UBound(aX, 2) WScript.Echo "s :", UBound(aX, 1) - LBound(aX, 1) + 1 _ , UBound(aX, 2) - LBound(aX, 2) + 1 i = 0 For Each e In aX WScript.Echo i & ":", e i = i + 1 Next End Sub ' showAFE you can use code like showAFE "VTA according to XlsRange:", getXlsRange("VTA", "B3:D4") showAFE "VTA according to AdoRows:", getAdoRows("SELECT * FROM [VTA$B3:D4]") to get your surprise of the weekend: For Each: VTA according to XlsRange: type: 8204 Variant() dims: 2 lb : 1 1 ub : 2 3 s : 2 3 0: 1 1: 2 2: 3 3: 4 4: 5 5: 6 For Each: VTA according to AdoRows: type: 8204 Variant() dims: 2 lb : 0 0 ub : 2 1 s : 3 2 0: 1 1: 3 2: 5 3: 2 4: 4 5: 6 and despair: Mr. Stumblegates type system hides the fact that these two arrays have a very different nature (and the difference between fixed and dynamic arrays is ignored too) You can create all kinds of arrays in VBScript as long as they are zero-based (no chance of creating and/or restructuring Range-born arrays and keep their (accidential!) one-based-ness) Getting one set of data with (necessarily) one layout via two different methods will deliver the data with two different structures If you ask "For Each" to enumerate the data, the sequence you get is determined by the iterator and not predictable (you have to check/experiment). (Accentuating the freedom/role of the iterator is the one nugget in AutomatedChaos' first answer) [Don't read this, if you aren't interested in/can't stand a pedantic diatribe: which still has a better score than AnthonyWJones' contribution, because at least one person who admittedly has anderstood neither question nor answer upvotes it, because of the reference to .ArrayList - which isn't relevant at all to armen's question, because there is no way to make an ArrayList multi-dimensional (i.e.: accessible by the equivalent of al(1,2,3)). Yes "IEnumerable" (a pure .NET concept) and "multithread" are impressive keywords and there are 'live' collections (e.g. oFolder.Files) that reflect 'on the fly' modifications, but no amount of (single!)-threading will let you modify a humble VBScript array while you loop - Mr. Stumblegates is a harsh master: Dim a : a = Array(1, 2, 3) Dim e WScript.Stdout.WriteLine "no problem looping over (" & Join(a, ", ") & ")" For Each e In a WScript.Stdout.Write " " & e Next ReDim Preserve a(UBound(a) + 1) a(UBound(a)) = 4 WScript.Stdout.WriteLine WScript.Stdout.WriteLine "no problem growing the (dynamic) array (" & Join(a, ", ") & ")" WScript.Stdout.WriteLine "trying to grow in loop" For Each e In a WScript.Stdout.Write " " & e If e = 3 Then On Error Resume Next ReDim Preserve a(UBound(a) + 1) If Err.Number Then WScript.Stdout.Write " " & Err.Description On Error GoTo 0 a(UBound(a)) = 5 End If Next WScript.Stdout.WriteLine output: no problem looping over (1, 2, 3) 1 2 3 no problem growing the (dynamic) array (1, 2, 3, 4) trying to grow in loop 1 2 3 This array is fixed or temporarily locked 5 Another elaboration of a blanket statement: Even good programmers make mistakes, especially if they are eager to help, have to work under unfavorable conditions (Mr. Stumblegates did his utmost to make sure that you can't use/publish VBScript code without extensive testing), have a job and a live, or just a bad moment. This, however, does not change the fact that some code fragments/statements are useless or even dangerous to SO readers who - because of votes - think they have found a solution to their problem. Quality of code/text is an essential property of the content alone, who wrote it is just accidential. But how to be 'objective' in a context where "Jon Doe's code" is the natural way to refer to lines like for i = 0 to ubound(myArr) for y = 0 to ubound(myArr, 1) [UBound(a) and UBound(a, 1) are synonyms, so this will create havoc as soon as the UBounds of the different dimensions are not (accidentially) the same] and votes for content are summed up under the reputations of persons? (Would SO list millions of answers without the reputation system? Would I put less time/work in my contributions without the points? I hope/guess not, but I'm a human too.) So I encourage you to downvote this elaborate (at least) until I correct the limit of 60 in my getDimensions() function. You can't hurt my feelings; I think I'm blameless, because all I did was to rely on the docs: Dimensions of an array variable; up to 60 multiple dimensions may be declared. (What I'm a bit ashamed of is that I had feelings of superiority, when I looked at the 999 or the 60000 in other people's code - as I said: I'm only human too; and: Don't put your trust in Mr. Stumblegates, but check: Dim nDim For Each nDim In Array(3, 59, 60, 62, 64, 65, 70) ReDim aDim(nDim) Dim sDim : sDim = "ReDim a" & nDim & "(" & Mid(Join(aDim, ",0"), 2) & ")" WScript.Echo sDim On Error Resume Next Execute sDim If Err.Number Then WScript.Echo Err.Description On Error GoTo 0 Next output: ReDim a3(0,0,0) ... ReDim a64(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0) ReDim a65(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) Subscript out of range ... ) Not to conclude in destructive mode: I still hope that my harping on the topic "bounds used in nested loops to specify indexers (especially such of different ranges)" will magically cause a lot of code lines here to be changed in the near future - or aren't we all students at Hogmond? ]
Use nested For loops, instead of For Each for i = 0 to ubound(myArr) for y = 0 to ubound(myArr, 2) ' do something here... next next
chart datapoint operand usage
In the code snippet below I am attempting to compare two data points as I am trying to put all low value points in a pie chart dataset into on "Other" datapoint. I am getting an "Cannot apply operator <> to operands of type System.....DataPoint and System.....DataPoint" on this code line " If pointValue <= minValue AndAlso Me.series.Points(index) <> colectedDataPoint " Dim collectedValue As Double = 0.0 For index As Integer = 0 To Me.series.Points.Count - 1 Dim pointValue As Double = Math.Abs(Me.series.Points(index).YValues(0)) If pointValue <= minValue AndAlso Me.series.Points(index) <> colectedDataPoint Then ' Add point value to the collected value collectedValue += pointValue ' Add point to supplemental series Me.supplementalSeries.Points.Add(Me.series.Points(index).Clone()) ' Remove point from the series Me.series.Points.RemoveAt(index) index -= 1 End If Next but yet if I write the same loop in C# that equivalent line is fine; this.series.Points[index] != colectedDataPoint anyone have a solution since the whole project is written in vb.net and i'd prefer to keep it uniform.