MATLAB: Array of structure initialization in CLASS properties - arrays

I would like to create a file which will store properties containing desired values.
Each property has to be defined as an array of struct.
My current way of array of struct initialization:
classdef myClass < handle
properties(Constant)
myProp1 = struct(...
'Name', {'A','B'},...
'Value', {'1','2'});
end
end
How I wish to write my array of struct(which I feel is more clean and readable):
classdef myClass < handle
properties(Constant)
myProp1(1).Name = 'A';
myProp1(1).Value = 1;
myProp1(2).Name = 'B';
myProp1(2).Value = 2;
end
end
How should I go about achieving this?
Thanks

I think it's not possible to create structures in the properties definition like you proposed. (See my comment on your question). An alternative is to create the array of structs in the constructor. Use (SetAccess=private), so that the properties may not be changed from outside.
% myClass.m
classdef myClass < handle
properties(SetAccess=private)
myProp1 = struct
end
methods
function obj = myClass() % constructor
obj.myProp1(1).Name = 'A';
obj.myProp1(1).Value = 1;
obj.myProp1(2).Name = 'B';
obj.myProp1(2).Value = 2;
end
end
end

You can solve this issue by using object composition.
It seems that the property myProp in myClass represents something else. For sake of simplicity I will assume it is a person (you will need to adapt the example to cover your needs). You can create a Person class with properties Name, Value, ParentName and use it in your class. The property section in myClass would look like this:
myProp(1) = Person(name1, value1, parent_name1);
myProp(2) = Person(name2, value2, parent_name2);
...
myProp(N) = Person(nameN, valueN, parent_nameN);
Alternatively you can prepare your Person class to accept arrays as inputs:
names = {name1, name2, ..., nameN};
values = [value1, value2, ..., valueN];
parent_names = {pname1, pname2, ..., pnameN};
... %//possibly more code here
myProp = Person(names, values, parent_names);
and the class Person would take care of always keep them in the right order, provide setters and getters, etc.
A stub of a Person class for the first solution would look like this (a class accepting arrays would be longer):
classdef Person < handle
properties (Access = private)
name = '';
value = 0;
parent_name = '';
end
methods (Access = public)
function this = Person(name, value, parent_name)
this.SetName(name);
this.SetValue(value);
this.SetParentName(parent_name);
end
function SetName(this, name)
this.name = name;
end
function SetValue(this, value)
this.value = value;
end
function SetParentName(this, parent_name)
this.parent_name = parent_name;
end
end
end

There's nothing wrong with your original way of setting up myProp.
But if you're concerned just about readability, you could add a private static method called something like makeMyProp, which can be laid out as attractively as you want, which returns a filled out structure myProp.
Then, in the properties section, say myProp = myClass.makeMyProp;.

classdef myClass < handle
properties(Constant)
myProp1a = struct('Name','A','Value',1);
myProp1b = struct('Name','B','Value',2);
myProp1 = [myClass.myProp1a, myClass.myProp1b];
end
end

You could use enumeration(yes, this apparently exists in MATLAB).
An example usage would be:
classdef ExampleEnum < uint8 %// Can also be another datatype
enumeration
%// name value
A (1)
B (2)
end
end
Then MATLAB automatically uses the string or the value depending on how you use your enum object (this is mentioned in the documentation).

Related

How to transform a list to an array in kotlin

I have a list
val rewardList: List<Reward>
class Reward(
val nameBefore: String
val amountBefore: Long
)
I want to have
val rewardArray: Array<TransReward>
class TransReward(
val nameAfter: String
val amountAfter: Long
)
There is name mapping involved and I can't figure out a good way to change list to array.
P.S. The class design is previous code in the system so I can't change it.
To transform List to Array you could use .toTypedArray(),but in your case you can't transform List<Reward> to Array<TransReward> because the class type are different.
My solution is to transform your Reward to TransReward first and then use .toTypedArray()
val rewardList: List<Reward>
class Reward(
val nameBefore: String
val amountBefore: Long
){
fun toTransReward(): TransReward = TransReward(
nameAfter = this.nameBefore,
amountAfter = this.amountBefore
)
}
// use it like this
val rewardArray : Array<TransReward> = rewardList.map{ it.toTransReward() }.toTypedArray()

Actionscript 3.0 - Sort an array of instances by their properties?

I have an Array which has Class instances in it.
These class instances have several properties.
Let's say I want to sort this array by the name property of each instance.
public class Thing
{
public var name:String;
public function Thing(name:String)
{
this.name = name;
}
}
And here is what the Array might look like:
var ar:Array = new Array(new Thing("Apple"), new Thing("Compass"),
new Thing("Banana"), new Thing("Alligator"));
After sorting it and looping through it to trace each instance's name property, it should output like this:
Alligator, Apple, Banana, Compass
You could sort by
ar.sortOn(property, options);
in your case the property would be "name" and option would ARRAY.ASCENDING
PS: I havent tried, but give it a go: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sortOn()
sortOn should probably work, or you can pass it through your own custom sort function:
private function _sortArray( a:Thing, b:Thing ):int
{
if ( a.name < b.name )
return -1; // a goes before b
else if ( a.name > b.name )
return 1; // b goes before a
return 0; // order doesn't matter
}
You can then call it via:
ar.sort( _sortArray );
Sort functions take two parameters of the type stored in the array (in your case, Thing), and return either <= -1 if a should go before b, >= 1 if b should go before a, or 0 if the order doesn't matter (i.e. the names are the same). You can compare pretty much anything to get the sorting you want. E.g., to get a random sort:
private function _sortArray( a:Thing, b:Thing ):int
{
if ( Math.random() < 0.5 )
return -1;
return 1;
}

Implement property read and read&write for fields of an array of records, inside a class

I would like to know if I can create an array of records in a class, where some fields are read-only properties, while others are for read and write.
I could think an example like this:
unit clsCustomers;
interface
uses
Classes;
type
TUnitsCategory = (type1, type2, type3, type4);
TCustomer = record
ID : LongWord;
name : string[25];
surname : string[25];
category : TUnitsCategory;
end;
TCustomers = array of TCustomer;
CCustomers = class
private
mycustomers : TCustomers;
protected
...
published
property customer[index: LongWord]: TCustomers //
read mycustomer[index].ID; // <-- just to say...
read mycustomer[index].name write mycustomer[index].name; //
end;
Here we have an array of customers, that I want to be accessible through the instance of this class...
I read about how to implement an array property and I wondered if I would like to have the "ID" field as read only, whereas other fields accessible in read and write.
I think the closest you can get is something like this:
CCustomers = class
private
mycustomers : TCustomers;
public
property customerID[index: LongWord]: LongWord read mycustomers[index].ID;
property customerName[index: LongWord] read mycustomers[index].name write mycustomers[index].name;
...
end;

data to structure in vb.net

I have this structure in Visual Basic .net
Private Structure queueT
Public name As String
Public parent As String
Public limitat As Integer
Public maxlimit As Integer
And this is the data I get, which I have stored in a one dimensional String array (just pasting 3):
!re=.id=*10000B0=name=Up-PBX=parent=Up=packet-mark=pack_pbx=limit-at=256000=queue=PCQ_Up=priority=1=max-limit=512000=burst-limit=0=burst-threshold=0=burst-time=00:00:00=invalid=true=disabled=true=comment=PBX
!re=.id=*10000C7=name=Down_Mauro=parent=Down=packet-mark==limit-at=315000=priority=8=max-limit=5000000=burst-limit=0=burst-threshold=0=burst-time=00:00:00=invalid=false=disabled=true
!re=.id=*10000C8=name=Down_Mauro_dom=parent=Down_Mauro=packet-mark=pack_Mauro_dom=limit-at=40000=queue=PCQ_Down=priority=2=max-limit=400000=burst-limit=0=burst-threshold=0=burst-time=00:00:00=invalid=false=disabled=true
I need to store the information in my structure so it looks like this:
queueT.name = UP-PBX
queueT.parent = UP
queueT.limitat = 256000
queueT.maxlimit = 512000
I only need the information mentioned above, not the rest. How can I do that?
Thanks!!
It looks like it's a key/value pairing after the first value. From your sample something like this could work.
Private Function queueTParse(item As String) As queueT
Dim queueValues = item.Split("=")
Dim queueTItem = New queueT
For i As Integer = 1 To queueValues.Length - 1 Step 2
Select Case queueValues(i)
Case "name"
queueTItem.name = queueValues(i + 1)
Case "parent"
queueTItem.parent = queueValues(i + 1)
Case "limit-at"
queueTItem.limitat = queueValues(i + 1)
Case "max-limit"
queueTItem.maxlimit = queueValues(i + 1)
End Select
Next
Return queueTItem
End Function

Efficient way to filter an Object Array on a specific property?

I have an array of objects with different properties and I need to filter the array in a way that a specific property is not duplicated.
For example:
var array:Array = [{foo:"a1", bar:"b1", baz:"c1"},
{foo:"a2", bar:"b2", baz:"c2"},
{foo:"a3", bar:"b1", baz:"c3"},
{foo:"a1", bar:"b4", baz:"c2"},
{foo:"a0", bar:"b3", baz:"c1"}];
Now suppose I want to filter the objects on the property baz. What is the most efficient way of filtering the array, so that no two elements have the same value for baz after the operation?
In my example, the result should only contain:
var result:Array = [{foo:"a1", bar:"b1", baz:"c1"},
{foo:"a2", bar:"b2", baz:"c2"},
{foo:"a3", bar:"b1", baz:"c3"}]
since the other objects would have duplicate entries for the baz property.
The order of the result array is not important, neither is which object of those with identical values for baz makes it into the result array.
Update:
The object array is used as a dataprovider to populate a s:Datagrid with information about chatrooms. The objects in the array carry related information (like the room's ID on the server and some other config settings).
The baz property I used in my example is actually the ID of the language the chat room is configured to use and I want to create a s:DropDownList with which I can filter the Datagrid for individual languages (e.g. show all rooms that use "German").
It is very likely to have many objects with the same language ID, but I only want each language Id to show up once in the DropDownList.
I need to extract that information from the Datagrids's dataprovider (the source array) and cannot retrieve my languages directly since the DropDownList is part of a generic DatagridHeaderRenderer that is used in many different Datagrids with different data.
private var array:Array = [{foo:"a1", bar:"b1", baz:"c1"},
{foo:"a2", bar:"b2", baz:"c2"},
{foo:"a3", bar:"b1", baz:"c3"},
{foo:"a1", bar:"b4", baz:"c2"},
{foo:"a0", bar:"b3", baz:"c1"}];
private var filteredArray:Array;
private var keys:Object = {};
private function filterArray():void{
filteredArray = arr.filter(removeDupes);
}
private function removeDupes(item:Object, idx:uint, arr:Array):Boolean {
if (keys.hasOwnProperty(item.baz)){
return false;
} else {
keys[item.baz] = item;
return true;
}
}
private function resetFilter():void{
filteredArray = new Array();
keys = {};
}
Modified from multiple sources but primarily: http://blog.flexexamples.com/2007/08/05/removing-duplicate-items-from-an-array-using-the-arrayfilter-method/
Or you could just use an arrayCollection and its built-in filterFunction. See: http://cookbooks.adobe.com/post_Using_the_to_ArrayCollection_s_filterFunction-5441.html
On the surface of it looks like it should work. Using Array.filter is usually about twice the time of doing the same thing in a loop.
I'd argue that' Dom's removeDupes function doesn't do exactly what's required, although it might be a more generic approach (if, for example, the === isn't a good comparison function, then this gives you a way of extending it.) But using hasOwnPropery is a big no-no. You should never touch it - that function only exists for ES compatibility. It is evil otherwise - both a potential security hole (as it is defined on Object.prototype and thus is easy to override for the foreign code) and is slow (for the same reason - the lookup of the functions defined on prototype is slower then those defined in a class).
public function Test()
{
super();
var array:Array = [{foo:"a1", bar:"b1", baz:"c1"},
{foo:"a2", bar:"b2", baz:"c2"},
{foo:"a3", bar:"b1", baz:"c3"},
{foo:"a1", bar:"b4", baz:"c2"},
{foo:"a0", bar:"b3", baz:"c1"}];
this.removeDuplicates(array, "baz").map(this.objectTracer);
// { foo : a3, baz : c3, bar : b1 }
// { foo : a1, baz : c2, bar : b4 }
// { foo : a0, baz : c1, bar : b3 }
}
private function objectTracer(object:Object, index:int, all:Array):void
{
var result:String = "";
for (var p:String in object)
result += ", " + p + " : " + object[p];
if (result) result = result.substr(2);
trace("{ " + result + " }");
}
private function removeDuplicates(array:Array, on:String):Array
{
var result:Array = array.concat();
// note that since we use `Dictionary' the
// the comparison between objects is the same as `==='
// if all values are strings, you can use `Object' to
// save some space.
var hash:Dictionary = new Dictionary();
var temp:Object;
for (var i:int, j:int = result.length - 1; j >= i; j--)
{
temp = result[j][on];
if (temp in hash)
{
result[j] = result[i];
j++; i++;
}
else hash[temp] = true;
}
// note that we could `shift()` until we get to `i'
// but when we do it, we actually reallocate the array every time
// so `slice()' must, in theory, be more efficient
return result.slice(i);
}

Resources