Whats the use of GetLowerBound()? - vb.net

The lowerbound of an array is always zero in VB.net, even if the first element is set to Nothing. So why do we need to use GetLowerBound(dimension) to get the index of the first element of an array in a particular dimension?

As per documentation found here:
https://learn.microsoft.com/en-us/dotnet/api/system.array.getlowerbound?view=net-6.0
There can be arrays that do not start with index 0:
Note that, although most arrays in .NET are zero-based (that is, the
GetLowerBound method returns zero for each dimension of an array),
.NET does support arrays that are not zero-based. Such arrays can be
created with the CreateInstance(Type, Int32[], Int32[]) method, and
can also be returned from unmanaged code.

Related

Numpy - how do I erase elements of an array if it is found in an other array

TLDR: I have 2 arrays indices = numpy.arange(9) and another that contains some of the numbers in indices (maybe none at all, maybe it'll contain [2,4,7]). The output I'd like for this example is [0,1,3,5,6,8]. What method can be used to achieve this?
Edit: I found a method which works somewhat: casting both arrays to a set then taking the difference of the two does give the correct result, but as a set, even if I pass this result to a numpy.array(). I'll update this if I find a solution for that.
Edit2: Casting the result of the subtraction to a list, then casting passing that to a numpy.array() resolved my issue.
I guess I posted this question a little prematurely, given that I found the solution for it myself, but maybe this'll be useful to somebody in future!
You can make use of boolean masking:-
indices[~numpy.isin(indices,[2,4,7])]
Explanation:-
we are using numpy.isin() method to find out the values exists or not in incides array and then using ~ so that this gives opposite result and finally we are passing this boolean mask to indices

Trying to understand and translate a small bit of VB code

I'm in the middle of transferring some VB code to another language, but I don't understand what's supposed to be happening here.
Dim foo(7,0) as Date
Then later in the code I get something like foo(5,3) and I believe the output to be a Date object. There is no function written to describe foo so I'm assuming it's a multi-dimensional array. But cast as a Date? I'm confused, please help.
I don't know what's going on their either, because this:
Dim foo(7,0) as Date
declares a two dimensional array that is effectively a one dimensional array because the second dimension has an upper bound of 0...
... and then you claim that the second dimension is later indexed with 3, which is outside the bounds. foo(5, 0) would be fine, but the sixth row (if you want to think of the 5 that way) has 1 column, so retrieving the fourth is an IndexOutOfRangeException. Presumably this has been ReDim'd at some point between then and now
To have the debugger help you out, run the code, stop on it and point to foo or look in the LOCALS window:
Bounded in red is the variable analyzer as a tooltip and in the locals. It shows Date to be a 2D array. It also helpfully lists all the contents. Bounded in blue is the error you get if you try and access index 3 of an array that stops at index 0
Make that 2D array actually have an appreciable width:
And you can see it's just a block of Date

VB.NET "For each" versus ".GetUpperBound(0)"

I would like to know what is preferred...
Dim sLines() As String = s.Split(NewLine)
For each:
For Each sLines_item As String In sLines
.GetUpperBound:
For i As Integer = 0 To sLines.GetUpperBound(0)
I have no idea why the "For Each" was introduced for such cases. Until now I have only used .GetUpperBound, and I don't see any PRO for the "For Each".
Thank you
ps: When I use ."GetUpperBound(0)", I do know that I am iterating over the vector.
The "For Each" in contrast sounds like "I don't care in which order the vector is given to me". But that is just personal gusto, I guess.
Short answer: Do not use GetUpperBound(). The only advantage of GetUpperBound() is that it works for multi-dimensional arrays, where Length doesn't work. However, even that usage is outdated since there is Array.GetLength() available that takes the dimension parameter. For all other uses, For i = 0 to Array.Length - 1 is better and probably the fastest option.
It's largely a personal preference.
If you need to alter the elements of the array, you should use For i ... because changing sLines_item will not affect the corresponding array element.
If you need to delete elements of the array, you can iterate For i = ubound(sLines) to 0 step -1 (or the equivalent).
Short answer
You should always use For Each on IEnumerable types unless you have no other choice.
Long answer
Contrary to the popular understanding, For Each is not a syntactic sugar on top of For Next. It will not necessarily iterate over every element of its source. It is a syntactic sugar on top of IEnumerable.GetEnumerator(). For Each will first get an enumerator to its source then loop until it cannot enumerate further. Basically, it will be replaced by the following code. Keep in mind that this is an oversimplification.
' Ask the source for a way to enumerate its content in a forward only manner.
Dim enumerator As IEnumerator = sLines.GetEnumerator()
' Loop until there is no more element in front of us.
While enumerator.Next() Then
' Invoke back the content of the for each block by passing
' the currently enumerated element.
forEachContent.Invoke(enumerator.Current)
End While
The major difference between this and a classical For Next loop is that it does not depend on any length. This fixes two limitations in modern .NET languages. The first one has to do with the Count method. IEnumerable provides a Count method, but the implementation might not be able to keep track of the actual amount of elements it stores. Because of this, calling IEnumerable.Count might cause the source to be iterated over to actually count the amount of element it contains. Moreover, doing this as the end value for traditional For Next loop will cause this process to be done for every element in the loop. This is very slow. Here is an illustration of this process:
For i As Integer = 0 To source.Count() ' This here will cause Count to be
' evaluated for every element in source.
DoSomething(source(i))
Next
The use of For Each fixes this by never requesting the length of the source.
The second limitation it fixes is the lack of a concept for arrays with infinite amount of elements. An example of such cases would be an array containing every digit of PI where each digit is only calculated when you request them. This is where LINQ makes its entrance and really shines because it enables you to write the following code:
Dim piWith10DigitPrecision = From d In InfinitePiSource
Take 10
Dim piWith250DigitPrecision = From d In InfinitePiSource
Take 250
Dim infite2PiSource = From d In InfinitePiSource
Select d * 2
Now, in an infinite source, you cannot depend on a length to iterate over all of its elements. It has an infinite length thus making a traditional For Next loop an infinite loop. This does not change anything for the first two examples I have given with pi because we explicitly provides the amount of elements we want, but it does for the third one. When would you stop iterating? For Each, when combined with Yield (used by the Take operator), makes sure that you never iterate until you actually requests a specific value.
You might have already figured it out by now but these two things means that For Each effectively have no concept of bounds because it simply does not require them. The only use for GetLowerBound and GetUpperBound are for non-zero-indexed arrays. For instance, you might have an array that indexes values from 1 instead of zero. Even then, you only need GetLowerBound and Length. Obviously, this is only if the position of the element in the source actually matters. If it does not, you can still use For Each to iterate over all elements as it is bound agnostic.
Also, as already mentioned, GetLength should be used for zero-indexed multi-dimensional arrays, again, only if the position of the element matters and not just the element itself.

How to avoid multiple Iterations to search and assign one of the possible object property to a variable ?

How can we avoid multiple iteration to search for an object's property and if found then assign it to a variable else search for another key ?
eq we have Video Class with one of the field as videoType which can have values as hq(high-quality),normal(normal), def(default)..etc and so on.
From an array containing multiple video objects, how can we search and return a particular object in an order that if the array contains object with property hq then first return it,else search for normal and proceed so on. if a set of n keys are to be tested in the key set (hq,normal,def,....) then do we always need to iterate the entire array "n" times unless the key is found.
Can this be done is single iteration ? Do we need to first sort the original array in the order of occurrence of the keys in desired key set. I hope my problem statement is clear.
One possible solution for this would be to create separate NSMutableArrays for each videoType. Then, as you iterate once over your array of video objects, you check its array type and add the video to the correct array.
After you finished iterating, you create the final mutable array by concatenating the other array with addObjectsFromArray.
If you have a lot or variable list of video types, you can create the separate mutable arrays as values in an NSDictionary, where the keys are the video types. This way, you can get the target array with one step, by fetching it from the dictionary.

How to cut the size of my ArrayList?

Lets say my ArrayList got 20 elements. Well, sometime in runtime I will want it to only have 10 elements, so the other 10 indexes(from 9 to 19) don't exist at all. How do I do that?
Why are you using non-generic collections at all? Use List<T> instead. And you can use the Remove() method on it.
Since your working with ArrayLists, and not Arrays, just use ArrayList.Remove() for a single part, and ArrayList.RemoveRange(x, list.Count-x) for a range.
If you're looking to avoid using memory space for the elements that are not present, you can try with the TrimToSize method:
http://msdn.microsoft.com/en-us/library/system.collections.arraylist.trimtosize.aspx
It will minimize the array overhead, by limiting the capacity to the current items.
If they already exist, you'll need to remove them and then, call this method.
I'm not sure what you're looking for exactly, so more details would be great.
If you just want to remove the elements without changing the capacity, you can use ArrayList.RemoveRange:
http://msdn.microsoft.com/en-us/library/system.collections.arraylist.removerange.aspx
arrayList.RemoveRange(10, list.Count-10)
This method can be used with any other valid range, if you e.g. want to delete the first ten elements instead.