Converting an object into array/matrix? - arrays

I have an object in Matlab created from a third party toolbox. Within the object is a 3x65 double array. If I type the name of the object in the Matlab console, it lists all the contents, and specifically says this 3x65 array is a double. All I want to do is to extract this array into a separate Matlab array. But when I do something like:
x = object.ArrayIWant
I get the error "Access to an object's fields is only permitted within its methods." If I try the following:
x = get(object,'ArrayIWant)
I get the error "Conversion to double from 'toolboxfunction' is not possible. How do get access to this array?!

Look for "Get" methods in the class:
methods(object)
or
methods className
Say it says there is a method called GetArrayIWant, then you'd do:
x = object.GetArrayIWant();

Related

Error when trying to set array in userdefaults: Thread 1: "Attempt to insert non-property list object

I have solved the issue now, thanks for your help. I shouldn't have tried to save arrays with UITextViews, but I should have saved their text as strings instead. Here was the original question:
I have tried a lot, and googled a lot, but I can't solve this problem on my own. Whenever I try to save an array in userdefaults, it just is not working. I get the following error:
Thread 1: "Attempt to insert non-property list object (\n "<UITextView: 0x14001f800; frame = (0 0; 355 180); text = 'D'; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600003f01d10>; layer = <CALayer: 0x6000031c83e0>; contentOffset: {0, 0}; contentSize: {355, 30}; adjustedContentInset: {0, 0, 0, 0}>"\n) for key content"
I don't know what a non-property list object is. And I do not know how to solve the problem. Below is the lines of code that do not work.
var contentList: [Any] = []
let cl = defaults.array(forKey: "content")!
if cl.count != 0{
contentList += cl
}
contentList.append(label)
defaults.setValue(contentList, forKey: "content")
If I take out the last line of code by turning it into a comment everything runs just fine. How should I replace that line of code? I essentially want to save an array of UITextViews and make it larger every time I call a fucntion (this code is part of a larger function). The reason why I have created another two lists (cl and contentList) is that it helps me with a problem down the line. What I cannot understand however, is why the last line of code doesn't work. If anyone has any ideas, please help me, it would be much appreciated.
Use only String as stated in comments :
var contentList: [String] = []
let cl = defaults.array(forKey: "content")!
if cl.count != 0{
contentList += cl
}
If lbText = label.text {
contentList.append(lbText)
defaults.setValue(contentList, forKey: "content")
}
You can only store a very limited list of data types into UserDefaults, commonly referred to as "property list objects" (Since property list (or plist) files will only store the same data types.
To quote the Xcode docs on UserDefaults, in the section titled "Storing Default Objects":
A default object must be a property list—that is, an instance of (or for collections, a combination of instances of) NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary [or Data, String, NSNumber, Date, Array, or Dictionary types in Swift.] If you want to store any other type of object, you should typically archive it to create an instance of Data.
(I added the equivalent Swift types to the above quote in square brackets, since it looks like Apple hasn't updated it for Swift.)
That's worded a little awkwardly. The idea is that you can only store data of the types listed. Because the Array and Dictionary types are "container" types, you can store any combination of arrays and dictionaries that contain combinations of any of the above types. For example, you can store an array that contains a dictionary, 3 dates, 2 floats, a Double, some Data, and 2 arrays, and those dictionaries and arrays can contain other dictionaries and/or arrays.)
It is almost always wrong to archive UIView objects like UITextViews. You should save the text properties of your text views instead.
If you want to manage a vertical stack of UITextView objects, I suggest adding a vertical stack view to your user interface, and then writing code that adds or removes UITextView subviews to your stack view. You should be able to find plenty of examples of adding and removing objects from stack views online. (It's really easy.)
If you want to manage a scrolling list of feeds of arbitrary length, you might want to use a table view or collection view instead. Those require that you set up a data model and implement a "data source". That takes a little practice to get right, but is very powerful.

How to Create a Globally Accessible 2d Array in C++/CLI

I've been having a lot of trouble making an array that is accessible to all the functions in my class in C++/CLI. Since it's C++/CLI, std::vector doesn't work. Boost::array throws an error about unmanaged types being used with managed types. I don't want to use a pointer array because I want to get the size of the array. System::List is too slow (every ms matters in my program, but if it helps, I don't care about write speeds to the array, only read speeds of one element at a time). cliext::vector was the closest I got to getting this to work.
I created a single dimensional cliext::vector with an int, and it worked. However, when I tried to use
cliext::vector<cliext::vector<int>> test;
it failed with a similar error as the one below. Here is how I used it in my class:
The header:
cliext::vector<Color> test;
I set values for it in the constructor:
test = gcnew cliext::vector<Color>(5);
test[0] = Color(255,255,255);
I then tried to make a class that would store 3 variable for color. Here is the header file. The constructor just sets the r,g,b values:
namespace FrameCalculator {
class Color {
public:
Color(int r, int g, int b);
int r;
int g;
int b;
};
However this didn't work, and it threw the error below:
1>E:\Microsoft Visual
Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\cliext\vector(1091):
note: see reference to class template instantiation
'cliext::impl::vector_base<_Value_t,false>' being compiled
1> with
1> [
1> _Value_t=FrameCalculator::Color
1> ]`
and
1>E:\Microsoft Visual
Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\cliext\vector(615):
error C3671: 'cliext::impl::vector_impl<_Value_t,false>::SyncRoot::get':
function does not override 'System::Collections::ICollection::SyncRoot::get'
1> with
1> [
1> _Value_t=FrameCalculator::Color
1> ]`
There were about 5 of each of these errors. What am I doing wrong? How do I get a 2d array that's not slow, is globally accessible. I don't need both arrays to be dynamic (I'd prefer them not to). I know the inner array will have 3 elements, but I won't know the outer array size at compile time. How do I achieve this?
You can not create a vector of .Net class object. You need a vector of handle types.
test = gcnew cliext::vector<Color^>(5);
Also your class objects must be of type ref class
ref class Color
Assignment is done with always creating a new object
test[0] = gcnew Color(255,255,255);
You can also use completely unmanaged types, but than you are forced to use pointers to this data in your C++/CLI code.
Managed types can never own unmanaged types. They may own a pointer to an unmanaged type.
So you may get all you anmanaged data into one unmanaged class and this data is accessed from the managed code.

Accessing instance properties inside of an array

I've imported several images into an actionScript 3 document. I've turned them all into symbols (movie clips) and given them instance names to reference from ActionScript.
Ok, so I'm putting the instances into an array so I can loop through them easily, but for some reason, whenever I'm putting in the instance name, I do a trace on the value in the array and it's giving me the symbol object back, rather than the instance object.
Basically trying to loop through the array to make each instance's visibility = false
Here's a sample:
var large_cap_extrusion_data: Array = new Array();
large_cap_extrusion_data[0] = large_cap_extrusion_menu_button;
large_cap_extrusion_data[1] = extrusion_border_large_cap
large_cap_extrusion_data[2] = "Large Cap";
large_cap_extrusion_data[3] = large_cap_main_menu_button;
var extrusion_data: Array = new Array();
extrusion_data[0] = large_cap_extrusion_data;
trace(extrusion_data[0][0]);
The traces gives:
[object large_cap_menu_button]
(the parent symbol)
rather than:
"large_cap_extrusion_menu_button"
I'd be very grateful if someone could tell me where I'm going wrong...
when you trace and object, by default it describes it type. What you want is the "name" property of the object.
Try this:
trace(extrusion_data[0][0].name);
that should give you the instance nema of the large_cap_menu_button rather than the class description. Either way, you have the right object I bet.

Scala's multidimensional arrays one more time

var channelsNumber = track.getNumberOfChannels()
var framesNumber = lastFrame - firstFrame
var frames = Array.ofDim[Int](channelsNumber)(framesNumber)
System.out.println(frames.length);
System.out.println(frames.length);
I try to define two dimensional array of integers. And I get this error:
[error] .../test.scala:58: type mismatch;
[error] found : Int
[error] required: scala.reflect.ClassManifest[Int]
[error] var frames = Array.ofDim[Int](channelsNumber)(framesNumber)
[error] ^
[error] one error found
What is "scala.reflect.ClassManifest[Int]"? Why channelsNumber passes and framesNumber, which is also an integer doesn't?
Now, you are calling method ofDim [T] (n1: Int)(implicit arg0: ClassManifest[T]) which you don't want to. Change the call to Array.ofDim[Int](channelsNumber,framesNumber) and the method ofDim [T] (n1: Int, n2: Int)(implicit arg0: ClassManifest[T]) will be called. You want to leave the implicit parameter group implicit.
And - class manifest is a way how to preserve type information in generic classes.
First your error: ofDim takes all the dimension in a single parameter list. You need
Array.ofDim[Int](channelsNumber, framesNumber)
Second, ClassManifest. Due to type erasure, and the fact than in the JVM, arrays are very much like generics, but are not generic (among other things, no type erasure), the generic method ofDim needs to be passed the type of the elements. That is the ClassManifest, which is close to passing a Class in java (you have to do the same in java -or pass an empty array of the proper type, in Collection.toArray- if you have a generic method that must return an array) This comes as as an implicit arguments, that is there is another parameter list with this argument, but the scala compiler will try to fill it automatically, without you having to write it in the code. But if you give a second parameter list, it means you intend to pass the ClassManifest yourself.

Delphi -> Delphi prism, how to use array of records?

I'm learning Delphi Prism, and i don't find how to write the following code with it :
type
TRapportItem = record
Label : String;
Value : Int16;
AnomalieComment : String;
end;
type
TRapportCategorie = record
Label : String;
CategoriesItems : Array of TRapportItem;
end;
type
TRapportContent = record
Categories : array of TRapportCategorie;
end;
Then, somewhere, i try to put items in the array :
rapport.Categories[i].Label:=l.Item(i).InnerText;
But it doesn't work.. Can someone enlight me?
Thanks!
You didn't specify exactly what "didn't work". You should include the error in questions like this.
Arrays are reference types, and they start out with the value nil. They need to be initialized before elements can be accessed.
You can do this with the new operator:
rapport.Categories = new TRapportCategorie[10]; // 0..9
Arrays are quite a low-level type. Usually it's better to work with List<T> instead.
So you'd declare:
Categories: List<TRapportCategorie>;
But lists also need initializing, using the new operator. Also, modifying the return value of the indexer on a list containing a value type will be modifying a copy, not the original, which leads to the next point.
Records are usually not the best data type for representing data, as they are not reference types; it's very easy to end up modifying a copy of the data, rather than the original data. It's usually best to use classes instead, where you can put all the initialization code (such as allocating the array or list) in the constructor.

Resources