LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Darin.K

Negative Values in Index Array or Array Subset

Status: New

There are many times when I need to grab the last element or last n elements of an array.   This usually involves a call to Array Size and then a subtraction, costing me time and block diagram clutter.  Array reversal is essentially free, but again costs clutter and clicks.  For common array types I have personal VIs to do the job, but that is just a band-aid with the proliferation of data types that I use.  My idea would be to treat negative values input to the index array or array subset VIs (for example) as counting from the end of the array.  The last value would have index -1 and so on.  To get the last n values I would put -n into the Array subset VI and that's it.   For expanding the Array Index VI, my preference would be that it counts down (-2,-3,-4,...).

 

 

 NegativeArrayIndex.png

33 Comments
tst
Knight of NI Knight of NI
Knight of NI

A co-worker of mine suggested this to me a few days ago and I remember I liked the idea a lot but had some reservation about the practicality of the implementation. Unfortunately, I don't remember what it was.

 

P.S. You can save yourself some clicks at least by creating a merge VI made up of a connected reverse and index and then place it in the palettes. Because it's a merge VI, you don't have to set a type.


___________________
Try to take over the world!
Darin.K
Trusted Enthusiast
Good tip on the merge VI.  It is not available in my current LV version, but with LV9 in the mail it's only a matter of time.  I'll keep an eye out in case you recall your reservation.  If the NI guys can make recursion work, this should be like falling off a log.  My concern is that there is some common construct that relies on the fact that indexing an array with a negative number returns the default value.  If so, I use it a whole lot less than I would this idea, but you don't want to go around deprecating a bunch of code.
altenbach
Knight of NI

Allowing negative indices will break a lot of existing code. I don't think it can be made backwards compatible and breaking existing code is a very bad idea.

 

Imagine doing a search operation (seach 1D array) and then replace the found element with a new value. If a match is not found, the search returns a -1 and would cause the replacement of the last element if this idea is implemented. This would be a significantly different result to the current behavior of the same code, where nothing would be replaced.

Darin.K
Trusted Enthusiast
That is why Replace Array Subset was not one of the VIs I suggested to have this fix.  I would prefer it and my own opinion is the use of -1 should be deprecated.  Since that is not going to happen, I am still looking for an example where changing the behavior for indexing an element to return a value would cause problems.  If you were around for the change from LV3 to LV4 you recall that the change in Boolean representation caused a problem for type casting which is easily fixed with a right-click option.  A similar 'Allow Negative Indexing' option for the replace functions seems like an easy fix for backwards compatibility (I'll go so far as to suggest it defaults to the current behavior).
Darin.K
Trusted Enthusiast
I guess the boolean change was LV4 to LV5.  LV3 to LV4 was just so painful that I tend to think everything happened then.
tst
Knight of NI Knight of NI
Knight of NI

Breaking existing code is certainly a possibilty and a good reason not to do this. This could happen in any place where people calculate the value (even for Index Array) and there's no way of knowing that in advance. It's possible I even did this myself (relying on negative indices returning the default value).

 

Another drawback to this is that the indices will be off by 1. In the positive direction, 1 is the second element. In the negative one, it will be the first. This is likely to cause various off-by-1 bugs and was probably the reservation I originally had.

 

One way of working around this is by adding a new "Reverse Index Array" primitive (as opposed to just checking an option on the existing one), but I believe NI doesn't like adding primitives which replace code which is so easy to create on our own.

 

As for the merge VI, which version are you using? They've been around since at least 7.0.


___________________
Try to take over the world!
altenbach
Knight of NI

Also remember that you could simply insert a "reverse array", because it can often be done without touching the array data at all, and thus virtually without any CPU overhead.

 

A quote from here:

"Finally to answer your Reverse 1D Array question. It's a little tricky, because internally the reverse array function will not allocate a new buffer (just reverse the pointer values), but as soon as you connect the output to a sub-VI or a Call Library Function the data will be copied."

 

------------------------------

 

Darin.K wrote: That is why Replace Array Subset was not one of the VIs I suggested to have this fix.

 

It is not very good to have exceptions where the behavior changes for similar inputs of different functions. The behavior needs to be global.

 

PJM_Labview
Active Participant

I must be missing something, but if you want to get the last elements of an array, why don't you use the delete from array primitive (see attached image)?

 

delete from array.png



  


vipm.io | jki.net

Darin.K
Trusted Enthusiast

I agree with altenbach that global behavior is best, and I'd do a happy dance if every array VI behaved this way.  I think with the right-click option to turn the behavior on or off all of them could.   As far as I can tell the only impediment is the use of '-1' as a code for not matching in a search.  In my text based projects, this is easily dealt with.  The explicit value -1 would not appear anywhere in my code except for a single constant definition in a header file.  Anybody who has developed text-based code knows that they will not be very popular around the office if they sprinkle their code with numeric constants.  LV (IMO) has never taken itself quite so seriously as a formal language, so it is a common and accepted practice to wire in a ton of numeric constants.  If you are good you add labels, but even that is not as common as it should be.  Therefore, a lot of code probably compares the value returned by a search to -1.  I would like the return value changed to - 2 billion (or whatever the I32 limit is), or some suitable large value and have a numeric constant created for it.  All array functions could ignore this index value and behave as before.   It is still less than zero, so those comparisons are unaffected, as is all code where the return value from the search is passed directly to an indexing array.  The only code broken is comparison to -1.  I am likely in the minority here, but I consider that to be poor form and weening people away is not necessarily a bad think.  I probably should have suggested this ten years ago, but back then I had real problems with LV, the fact that this is high on my wishlist shows that they have made tremendous progress.

 

I agree with tst that there is potential for off-by-one bugs.  Having used my workaround for years, I think it actually is fairly natural.  Of course there is an easy fix to this, LV could do the sensible thing and start indexing arrays at 1 instead of 0.  0 could also be used as the code which is ignored.  (No emoticons so I should point out that this is just a sick joke that I should save until April 1).

Darin.K
Trusted Enthusiast

Thanks for the example, Delete from array is what got me thinking that implementing negative indices would be possible.   It works well in many cases, but misses the functionality of grabbing the n-th from the last element directly.  Perhaps I have not fully understood its operation, it seems tricky to use for higher dimensional arrays.   By then, it looks better to do the math.   I don't consider this a hard problem, my issue is more with code clutter and readibility.  With just a little more 'under the hood' I could do a lot of my array manipulations more elegantly.