LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Initializing array of clusters of different data types

Solved!
Go to solution

I am converting a JSON string to a cluster that contains an array. The elements of this array are again clusters which contain various amount and types of data, as below:

 

examplesOfArrays.png

 

Is there a way of storing any of these arrays in a single initialized array? Essentially, I thought, I could just initialize a cluster of a single 1-D array containing clusters of any placeholder data type, then replace only the array (which is an array of clusters (of n elements)), as below:

 

problem.png

 

The broken wire says "You have connected two clusters with different contents. Cluster Dt,  a cluster of 5 elements, conflicts with cluster Dt, a cluster of 1 elements.".

I understand why this error comes up, but also not because I am not replacing the cluster in the array, but only the array itself... 

Many Thanks!

0 Kudos
Message 1 of 8
(5,045 Views)

There is a datatype that accepts anything - a variant. Can you explain generally what you are trying to do? There may be a better way

0 Kudos
Message 2 of 8
(5,020 Views)

I looked at the variant option, too. However, lets say I convert my array to a variant. To then deconstruct the variant back to the original array (with its clusters of various datatypes) I need to pass the datatype to the 'Variant to Data Function', which kind of renders the whole process useless again.

 

What I am doing is this: I am getting a JSON string from an instrument, from which I need to extract some data. Using the JKI JSON Toolkit, I get out a cluster "Value" which contains and array "Dt". The Dt array is always one-dimensional, but changes in length. Each array element is itself a cluster of channel info data ( an int for channel number, a string for channel name, a double for measured value, etc.). The data inside this cluster depends on the request I have sent to the instrument (and its corresponding response). So if I have 5 channels, I have an array of 5 clusters, each containing fields a,b,c,d which comes from request 'WHAT_1?' while the response from 'WHAT_2?' results in an array of 5 clusters each containing fields e,f. I will ALWAYS have an array of clusters, what changes is the contents of the clusters.

0 Kudos
Message 3 of 8
(5,000 Views)
Solution
Accepted by topic author dougbock

From your explanation (although I'm still a bit unclear about the original goal regarding an initialized array) it seems like the easiest solution is to have multiple typedef'd clusters, one for each response type. In your example you have only 3, but I fear that it might be you have quite a few more? That would make this less appealing...

 

This would then look something like the following:

Example_VI_BD.png

 

This has a fairly annoying downside too - now all the processing needs to happen inside the case structure. Of course, you can make this a subVI too, and common functionality becomes subVIs and so on, but it's not fantastic... Then again, maybe they need separate processing regardless given their significant differences?

 

You might prefer to look at an OOP solution using a different child for each cluster type, but I expect you'd run into most of the same difficulties. Your advantage there would be that you could have all the data types inheriting from a parent class, with any shared code as either a parent method or a Dynamic Dispatch based API. The parent class would be the output type from a case structure, but you could place the deserializing code outside the case structure and just have a Class Object constant inside the case structure.

Example_VI_BD_OOP.png


GCentral
Download All
Message 4 of 8
(4,994 Views)

Thanks for your suggestion!

Your first snippet is almost exactly what I have now. Ideally I was going to pass the different possible arrays out of the case structure, with the type mismatch error happening here. So I guess to not over-complicate things I will have to do all my processing in each case structure and then only pass out similar data types. 

Many thanks for your input!

 

0 Kudos
Message 5 of 8
(4,985 Views)

With the OOP option, there is no need for the variant.  Just have a dynamic dispatch output for the object.

 

Also with OOP, you could use the Get Default Value to initialize the object from the class file path; no constants needed. 


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
0 Kudos
Message 6 of 8
(4,983 Views)

@crossrulz wrote:

With the OOP option, there is no need for the variant.  Just have a dynamic dispatch output for the object.

I don't quite follow... Where are you getting rid of the variant? I have a class object as the output but I don't see how to avoid using a variant with the JKI JSON toolkit (although I haven't used it at all).

 


@crossrulz wrote:

 

Also with OOP, you could use the Get Default Value to initialize the object from the class file path; no constants needed. 


Is this to avoid the case structure entirely? I assume you mean to use the message type enum or similar to determine the file path from the text matching the file name or similar?


GCentral
0 Kudos
Message 7 of 8
(4,980 Views)

I did not realize a JKI toolkit was being used.  So nevermind on the variant.

 

Yes, the thought was you could get some information from the JSON file to say what class was used and then get that classes default value.  This works well if you organize the code properly and use good naming.  I do this all the time with Configuration files.


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
Message 8 of 8
(4,936 Views)