LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
cbutcher

Directly access a Maps Keys and Values

Status: New

cbutcher_0-1644062153495.png

The top For loop + Unbundle is the current method to get the Keys and Values of all elements in a Map as arrays. If you need both, this is ok, but I'd prefer the second option, with a native node.

 

If you only want one (e.g. the Keys), then the For loop and Unbundle takes quite a bit more room than a similar-type of node (here the size is taken from the Collection Size node, and the paired outputs in the second row are from Matrix Size).

Can we have nodes to access the keys in particular, and perhaps the Keys + Values of a Map without requiring the For loop?


GCentral
10 Comments
crossrulz
Knight of NI

You can use the Collection Extensions package available through VIPM.  In that package is a Convert Map to Array.vim that will do the job.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
AristosQueue (NI)
NI Employee (retired)

1. R&D looked at this specific node during the map API design and concluded that purely converting the map to keys and values was relatively rare compared to "convert and filter". The For Loop notation elegantly solves the filtering and allows the pure conversion if needed. So there wasn't a compelling reason for the node.

 

But if it has nice utility, maybe we should add it anyway even if redundant? Maybe... unless there's a compelling reason against the node.

 

2. If we provide the direct lookup of keys and values, that forces a data copy into a new data structure -- the same as the For Loop. But having the direct node encourages the pattern of "get keys and values and then filter", which is a really bad pattern and would undermine the performance of the common case of "filter the keys/values". In general, we try to provide APIs where users, without deep knowledge of CS and data structure theory, "luck" into good performance patterns. The direct "get the arrays" node works against that.

 

Those arguments above were accepted by the team. I had another argument that I think also applies, but it was too anecdotal to be part of the API decision.

 

3. Yes, there are good use cases for getting all the keys and values as an array (usually for UI display), but there are bad cases where the fact that you're having to get those arrays should signal that you shouldn't be using a map in the first place. In my experience looking at user code in other languages, the bad cases are more common than the good cases. I didn't want to add a node that encouraged code that maybe shouldn't be written in the first place.

 

Given the above, we decided not to build this node. I'll leave the idea open for discussion, but unless there's some strong counterarguments or a pile of kudos, I'll be inclined to close it in the future.

 

PS: Is it too late to dissuade the Collections Extension package from including that function? Probably not. Oh well. 🙂

wiebe@CARYA
Knight of NI

>but there are bad cases where the fact that you're having to get those arrays should signal that you shouldn't be using a map in the first place. 


>But having the direct node encourages the pattern of "get keys and values and then filter", which is a really bad pattern and would undermine the performance of the common case of "filter the keys/values".

 

95% of the time I do not use maps and sets for performance, but simply to create an array of unique values.

 

If you need this function, being forced to work with the given tools, because what you want 'is not proper', feels very patronizing.

 

A .vim works though. And probably just as well as a function... To bad we all have to make (or copy) it.

AristosQueue (NI)
NI Employee (retired)

Honestly, I thought the For Loop solution was sufficiently light weight and the need for the pure arrays rare enough that I didn't expect this conversation to come up. Being "forced to" is an awfully strong statement for two nodes vs one node.

 

> To bad we all have to make (or copy) it.

 

I don't think "all" have to. Like I said, I expect most people will just use the "For Loop + Unbundle" without ever blinking at it. I think you're an outlier in needing this functionality so commonly as to be worth writing the VIM. If you need it, great, write it, but I think you're extrapolating your experience onto the wider group, and I don't think it applies.

 

Key phrase: I think. 🙂

 

We only have two and a half years of usage data on this feature, and seeing actual usage patterns for features typically takes five years in my experience. Thus it is too soon to tell if you're actually an outlier or just an early adopter. Ask me again in a few years.

 

Making LabVIEW code likely to be successful is R&D's job. We encourage good patterns and discourage others. We do this so that LabVIEW avoids the trap that some other languages set up where developers need deep knowledge to choose between two ways of accomplishing the same task. One person's "patronizing" is another person's "customer service", and the distinction will always be subjective to whether in serving most we happen to serve you the one that day. At the moment, I think adding this VIM to the common palettes would be a disservice to most users. I'm already monitoring code as it comes in from users (usually in bug reports) for common API patterns with the sets/maps... this is on my radar.

cbutcher
Trusted Enthusiast

So I included the "Keys + Values" example for 'completeness', but I don't really care for it all that much. If that's the main objection, would just a "Keys" node be more favourable possibility? I imagine this has more valid use cases?

Spoiler
when will I learn not to post ideas containing two parts... 😕 


As AQ surmised, the use case that I had when posting this was to take a set of String keys and populate a listbox ("for UI display"), and then on selection to use the value (via, at that point, Look In Map) to populate a subpanel or similar (value could be a VI ref, or perhaps an object containing the VI ref and other details and a method to handle subpanel insertion).

As an aside, can better performance (not that it really matters, but I'm curious) be achieved in this case using a hypothetical "keys" native node rather than the For loop, unbundle and autoindexing the top output (key)?
I note that C++'s std::map doesn't provide either of these functions, so perhaps a LabVIEW implementation would just be the For loop (or a C++ For loop) anyway?


GCentral
AristosQueue (NI)
NI Employee (retired)

cbutcher: We know of nothing that a single node would be able to do that would make it more efficient than the For Loop + Unbundle, and there are multiple cases where the For Loop will be more efficient (as noted above) than a single node.

wiebe@CARYA
Knight of NI

>cbutcher: We know of nothing that a single node would be able to do that would make it more efficient than the For Loop + Unbundle

 

Exactly. But a single node will look cleaner. And it will be more intuitive\easier to find.

AristosQueue (NI)
NI Employee (retired)

> And it will be more intuitive\easier to find.

 

Those are the two things that I do not want to enable for most users. I believe that's a disservice not a service for most users. You can create the .VIM for yourself, and at the moment, I'm content with that overall user experience -- most users don't have it, power users can create it.

pauldavey
Active Participant

The node would not work for cases where you have an array as the key/value data type.

 

I have made a VIM that returns the keys, and it has its uses of course. But there are also times when I end up replacing it with a For loop because I want to do something else as well.

 

The data copy is not a show-stopper in many cases, since maps don't have to be large. I would say most of my maps are not large at all.

wiebe@CARYA
Knight of NI

>The node would not work for cases where you have an array as the key/value data type.

 

Not until LabVIEW supports an array of arrays.

 

It all comes together 😎...

 

Of course the .vim can return an array of clusters of arrays. Sigh.