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()
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;
}
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;
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
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);
}