Push Object in AS3 - actionscript-3

I was wondering if it's possible to push values to an object like in Arrays:
array.push("value");
I wanna give each color a letter like a, b, c, ..
It should be like:
var colors = { "a" : "ffffff", "b" : "000000" };
How can I add now other colors with letters to this?

Simple as:
colors["c"] = "ff0000";
colors["d"] = "00ff00";
colors["e"] = "0000ff";
// etc
Hope that helps.

It's up to you to make a selection from an Object, a Dictionary or an Array. But if you want to use those "a","b","c" as keys you will want to use an Object or a Dictionary instance.
var colors:Object = {};
colors["a"] = "etc.";
colors["b"] = "etc.";
// or
var colors:Object = {};
colors.a = "etc.";
colors.b = "etc.";
// or
var colors:Object = {a:"etc.",b:"etc"};

Related

Can we recall a set of variable inside the Sequence Array?

I'd like to ask about my program bcs it doesn't work correctly. I want to recall a set of variable in two different Sequence Array. Here is my code.
// Array of Arrays
var SequenceGo:Array =
\[
{dt:dt1, P:P1, s0:s01, s:s1},
{dt:dt2, P:P2, s0:s02, s:s2},
{dt:dt3, P:P3, s0:s03, s:s3},
{dt:dt4, P:P4, s0:s04, s:s4},
{dt:dt5, P:P5, s0:s05, s:s5},
{dt:dt6, P:P6, s0:s06, s:s6},
{dt:dt7, P:P7, s0:s07, s:s7},
{dt:dt8, P:P8, s0:s08, s:s8},
{dt:dt9, P:P9, s0:s09, s:s9},
{dt:dt10, P:P10, s0:s010, s:s10},
\];
var SequenceBack:Array =
\[
{dtback:dt10back, P:P10, s0:s010, sback:s10back},
{dtback:dt9back, P:P9, s0:s09, sback:s9back},
{dtback:dt8back, P:P8, s0:s08, sback:s8back},
{dtback:dt7back, P:P7, s0:s07, sback:s7back},
{dtback:dt6back, P:P6, s0:s06, sback:s6back},
{dtback:dt5back, P:P5, s0:s05, sback:s5back},
{dtback:dt4back, P:P4, s0:s04, sback:s4back},
{dtback:dt3back, P:P3, s0:s03, sback:s3back},
{dtback:dt2back, P:P2, s0:s02, sback:s2back},
{dtback:dt1back, P:P1, s0:s01, sback:s1back}
\];
function onNext(index:int = 0):void
{
if (index >= SequenceGo.length)
{
return;
}
var aDataGo:Object = SequenceGo[index];
var aDataBack:Object = SequenceBack[index];
//variables
F = s_teganganst.value;
m = s_masjenst.value/10000;
v = Math.sqrt(F/m);
tp = 5000/v;
f = s_frekuensist.value;
w = 2*Math.PI*f;
aDataGo.dt += t;
aDataGo.s = aDataGo.s0 - A * Math.sin(w * aDataGo.dt);
aDataGo.P.y = aDataGo.s;
if(P10.y < 607){
aDataBack.dtback += t;
aDataBack.sback = - A * Math.sin(w * aDataBack.dtBack);
aDataBack.P.y = aDataGo.s + aDataBack.sback;
}
setTimeout(onNext, tp, index + 1);
}
Actually, code
aDataBack.P.y = aDataGo.s + aDataBack.sback;
is not a fit code for the animation because aDataBack is ordered inversely from aDataGo (we have to stay this inverse order for the proper animation in my program). I want to recall the variables based on its number, so each variable will match with another variable. For example,
P1.y = s1 + s1back;
P2.y = s2 + s2back;
P3.y = s3 + s3back;
P4.y = s4 + s4back;
//and so on
I've tried the code above, but it also doesn't work. Any other expression for calling some couples of variables just like my code above? Thanks!
I want to recall the variables based on its number, so each variable will match with another variable
Ok, there are two options.
Option one, simple and straightforward: compose a method to find the correspondent back object on spot:
function findBack(P:Object):Object
{
for each (var aDataBack:Object in SequenceBack)
{
if (aDataBack.P == P)
{
return aDataBack;
}
}
}
So, that piece of code would be
var aDataGo:Object = SequenceGo[index];
var aDataBack:Object = findBack(aDataGo.P);
The possible problem here is the performance. It is fine on the scale of 10 or 100 objects, but as (I suppose) you devise a particle system, the object count easily scales to thousands, and the amount of loop-searching might become cumbersome.
So I advise to prepare a pre-indexed hash so that you won't need to search each single time.
var SequenceBack:Array =
[
// ...
];
// Dictionary is a storage of key:value data, just like Object,
// but Dictionary allows Object keys.
var HashBack:Dictionary = new Dictionary;
for each (var aDataBack:Object in SequenceBack)
{
HashBack[aDataBack.P] = aDataBack;
}
I encourage you to read more about Dictionary class.
And so that piece of code would be
var aDataGo:Object = SequenceGo[index];
var aDataBack:Object = HashBack[aDataGo.P];

How to properly store array inside of a Record

var z = Record({a: []});
var a = new z({a: [1]});
var b = new z({a: [1]});
expect(Immutable.is(a, b)).to.be.true; // false
This returns false because [] is a mutable structure. So I've changed that code into this:
var z = Record({a: List()});
var a = new z({a: List([1])});
var b = new z({a: List([1])});
expect(Immutable.is(a, b)).to.be.true; // true
And it seems to work since Immutable.List is immutable. So is this the properly way of storing an array inside of a Record?
Thank you!
`int A[] = new int[5];` //creates the "A" array with an integer datatype
`int B[] = new int[5];` //creates the "B" array with an integer datatype
Would be the correct syntax. You can drop the expect(Immutable.is(a, b)).to.be.true; // true
You are probably getting an error because there is no data type in the syntax you provided above.
Hope this helps.

How to get nested deep property value from JSON where key is in a variable?

I want to bind my ng-model with JSON object nested key where my key is in a variable.
var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']"
Here I want to get value 5 from data JSON object.
I found the solution to convert "course.sections.chapter_index" to array notation like course['sections']['chapter_index'] this. but don't know how to extract value from data now
<script type="text/javascript">
var BRACKET_REGEXP = /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/;
var APOS_REGEXP = /'/g;
var DOT_REGEXP = /\./g;
var FUNC_REGEXP = /(\([^)]*\))?$/;
var preEval = function (path) {
var m = BRACKET_REGEXP.exec(path);
if (m) {
return (m[1] ? preEval(m[1]) : m[1]) + m[2] + (m[3] ? preEval(m[3]) : m[3]);
} else {
path = path.replace(APOS_REGEXP, '\\\'');
var parts = path.split(DOT_REGEXP);
var preparsed = [parts.shift()]; // first item must be var notation, thus skip
angular.forEach(parts, function (part) {
preparsed.push(part.replace(FUNC_REGEXP, '\']$1'));
});
return preparsed.join('[\'');
}
};
var data = {"course":{"sections":{"chapter_index":5}}};
var obj = preEval('course.sections.chapter_index');
console.log(obj);
</script>
Hope this also help others. I am near to close the solution,but don't know how can I get nested value from JSON.
This may be a good solution too
getDeepnestedValue(object: any, keys: string[]) {
keys.forEach((key: string) => {
object = object[key];
});
return object;
}
var jsonObject = {"address": {"line": {"line1": "","line2": ""}}};
var modelName = "address.line.line1";
var result = getDescendantPropValue(jsonObject, modelName);
function getDescendantPropValue(obj, modelName) {
console.log("modelName " + modelName);
var arr = modelName.split(".");
var val = obj;
for (var i = 0; i < arr.length; i++) {
val = val[arr[i]];
}
console.log("Val values final : " + JSON.stringify(val));
return val;
}
You are trying to combine 'dot notation' and 'bracket notation' to access properties in an object, which is generally not a good idea.
Source: "The Secret Life of Objects"
Here is an alternative.
var stringInput = 'course.sections.chapter_index'
var splitInput = stringInput.split(".")
data[splitInput[1]]][splitInput[2]][splitInput[3]] //5
//OR: Note that if you can construct the right string, you can also do this:
eval("data[splitInput[1]]][splitInput[2]][splitInput[3]]")
Essentially, if you use eval on a string, it'll evaluate a statement.
Now you just need to create the right string! You could use the above method, or tweak your current implementation and simply go
eval("data.course.sections.chapter_index") //5
Source MDN Eval docs.
var data = {
"course": {
"sections": {
"chapter_index": 5
}
}
};
var key = "course['sections']['chapter_index']";
var keys = key.replace(/'|]/g, '').split('[');
for (var i = 0; i < keys.length; i++) {
data = data[keys[i]];
}
console.log(data);
The simplest possible solution that will do what you want:
var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']";
with (data) {
var value = eval(key);
}
console.log(value);
//=> 5
Note that you should make sure key comes from a trusted source since it is eval'd.
Using with or eval is considered dangerous, and for a good reason, but this may be one of a few its legitimate use cases.
If you don't want to use eval you can do a one liner reduce:
var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']"
key.split(/"|'|\]|\.|\[/).reduce((s,c)=>c===""?s:s&&s[c], data)

GAS - Sort a flexTable by column

I understand that cellTable in GWT performs this (Sort FlexTable Inquiry) and I was wondering if anyone knew a way to emulate some of the column sorting behaviour using a flexTable in UiApp.
In my case it is only necessary for the app to sort the column once at creation, not have it sortable by the user on click. I have included my flexTable creation code below:
var flexTable = app.createFlexTable()
.setStyleAttribute('marginTop', '10px')
.setCellPadding(5)
.setCellSpacing(2);
for(var i = 0;i<(size-1);i++){
var class = "class" + (i+1);
var classCode = classObjectsIndex[loggedInUser][class];
var text10 = statusObjectsIndex[classCode].classname;
var text11 = statusObjectsIndex[classCode].homeworkstatus;
var text12 = statusObjectsIndex[classCode].classcalendarlink;
var anchor = app.createAnchor('Calendar', text12)
.setTarget('_blank');
var calPanel = app.createAbsolutePanel()
.add(anchor);
flexTable.setText(i, 0, text10);
flexTable.setText(i, 1, text11);
flexTable.setWidget(i, 2, calPanel);
if(text11 == "No homework set for this class"){
flexTable.setRowStyleAttribute(i, "backgroundColor", "#96bcfd")
flexTable.setRowStyleAttribute(i, "color", "#000000");
}else{
flexTable.setRowStyleAttribute(i, "backgroundColor", "#eca8a3");
flexTable.setRowStyleAttribute(i, "color", "#FFFFFF");
};
}
app.add(flexTable);
Due to the way in which the table is populated sorting the array the values are pulled from will not help.
This the first question I have posted here, please be gentle. If I could ask it in a better way, I have overlooked an obvious resource to get my answer or if there is more information I need to provide please let me know!
EDIT//////////////////////////////////
I was having trouble sorting using the code provided, very helpfully, by Serge and so I approached it slightly differently and created individual objects for each row of data. The advice given by both Serge and Zig helped me end up with this working solution, many thanks!
//create flexTable
var flexTable = app.createFlexTable();
flexTable.setStyleAttribute('marginTop', '10px')
flexTable.setCellPadding(5);
flexTable.setCellSpacing(2);
//create empty table array to store rowObjects
var tableArray =[];
//create rowObjects
for(var i = 0; i<(size-1); i++){
var rowObject = {};
var class = 'class' + (i+1);
var classCode = classObjectsIndex[loggedInUser][class];
rowObject.className = statusObjectsIndex[classCode].classname;
rowObject.homeworkStatus = statusObjectsIndex[classCode].homeworkstatus;
rowObject.link = app.createAbsolutePanel().add(app.createAnchor('Calendar',statusObjectsIndex[classCode].classcalendarlink));
if(statusObjectsIndex[classCode].homeworkstatus == "No homework set for this class"){
rowObject.BGColor = "#96bcfd";
rowObject.color = "#000000";
}else{
rowObject.BGColor = "#eca8a3";
rowObject.color = "#FFFFFF";
}
tableArray.push(rowObject);
}
//sort objects in array by homework status
tableArray.sort(function (a, b) {
if (a.homeworkStatus > b.homeworkStatus)
return 1;
if (a.homeworkStatus < b.homeworkStatus)
return -1;
return 0;
});
//populate flextable
for(var i = 0;i<(size-1);i++){
flexTable.setText(i,0, tableArray[i].className);
flexTable.setText(i,1, tableArray[i].homeworkStatus);
flexTable.setWidget(i,2, tableArray[i].link);
flexTable.setRowStyleAttribute(i, 'color', tableArray[i].color);
flexTable.setRowStyleAttribute(i, 'backgroundColor', tableArray[i].BGColor);
};
app.add(flexTable);
Theres nothing that prevents you from sorting the source array first. Just store each 5 columns (3 data columns plus background/foreground colors) as rows in another array and sort that other array. After sort populate the table.
I fully agre with Zig on this, here is an example of such an implementation to help you figure out how to approach it. (code not tested but should be right)
var flexTable = app.createFlexTable()
.setStyleAttribute('marginTop', '10px')
.setCellPadding(5)
.setCellSpacing(2);
var array = [];
var t0 = [];
var t1 = [];
var t2 = [];
var color = [];
var BGcolor = [];
for(var i = 0;i<(size-1);i++){
var class = "class" + (i+1);
var classCode = classObjectsIndex[loggedInUser][class];
t0.push(statusObjectsIndex[classCode].classname);
t1.push(statusObjectsIndex[classCode].homeworkstatus);
t2.push(app.createAbsolutePanel().add(app.createAnchor('Calendar',statusObjectsIndex[classCode].classcalendarlink)));
if(statusObjectsIndex[classCode].homeworkstatus == "No homework set for this class"){
color.push("#000000")
BGcolor.push("#96bcfd")
}else{
color.push("#FFFFFF")
BGcolor.push("#eca8a3")
};
array.push(t0,t1,t2,color,BGcolor);
}
// sort the array here
array.sort();// use other sort parameter if you want, search SO for examples
for(var n in array){
flexTable.setText(i, 0, array[n][0]);
flexTable.setText(i, 1, array[n][1]);
flexTable.setWidget(i, 2, array[n][2]);
flexTable.setRowStyleAttribute(i, array[n][3])
flexTable.setRowStyleAttribute(i, array[n][4]);
}
app.add(flexTable);

actionscript arrays merge

I posted my problem a few hours ago, but I think I figured out how to ask my question in a more comprehensible way.
This is my code:
// 1. Intro
var introPL1:Array = ["intro1","intro2","intro3","intro4"];
var introPL2:Array = ["intro5","intro6","intro7","intro8","intro9"];
var introPL3:Array = ["intro10","intro11"];
var introPL4:Array = ["intro12","intro13"];
var allIntro:Array = [introPL1,introPL2,introPL3,introPL4];
// 2. Clothes
var clothesPL1:Array = ["clothes1","clothes2","clothes3","clothes4","clothes5"];
var clothesPL2:Array = ["clothes6","clothes7","clothes8"];
var clothesPL3:Array = ["clothes9","clothes10"];
var clothesPL4:Array = ["clothes11","clothes12","clothes13"];
var allClothes:Array = [clothesPL1,clothesPL2,clothesPL3,clothesPL4];
// 3. Colored Numbers
var colNumPL1:Array = ["colNum1","colNum2","colNum3","colNum4","colNum5"];
var colNumPL2:Array = ["colNum6","colNum7","colNum8"];
var colNumPL3:Array = ["colNum9","colNum10"];
var colNumPL4:Array = ["colNum11","colNum12","colNum13"];
var allColNum:Array = [colNumPL1,colNumPL2,colNumPL3,colNumPL4];
var allStuff:Array;
allStuff = allIntro.concat(allClothes, allColNum);
trace(allStuff[4]);
When I trace allStuff[4] it displays "clothes1,clothes2,clothes3,clothes4,clothes5".
The thing is, I would like all the stuff to be in the allStuff array (without sub-arrays) and when I trace allStuff[4], I would like it to display "intro5" (the fifth item in the huge allStuff array).
the function you want to use then is concat
here's the example from adobe
var numbers:Array = new Array(1, 2, 3);
var letters:Array = new Array("a", "b", "c");
var numbersAndLetters:Array = numbers.concat(letters);
var lettersAndNumbers:Array = letters.concat(numbers);
trace(numbers); // 1,2,3
trace(letters); // a,b,c
trace(numbersAndLetters); // 1,2,3,a,b,c
trace(lettersAndNumbers); // a,b,c,1,2,3
it's pretty straight forward:
allStuff= allStuff.concat(introPL1,introPL2,introPL3,introPL4,clothesPL1,clothesPL2,clothesPL3,clothesPL4,colNumPL1,colNumPL2,colNumPL3,colNumPL4);
you could also do a
allStuff = []
for each(var $string:String in $arr){
allStuff.push($string)
}
for each array, or make it into a function
Okay, once you have declared your arrays like so, you need an additional operation to flatten your arrays allClothes and so on. Do like this:
function flatten(a:Array):Array {
// returns an array that contains all the elements
// of parameter as a single array
var b:Array=[];
for (var i:int=0;i<a.length;i++) {
if (a[i] is Array) b=b.concat(flatten(a[i]));
else b.push(a[i]);
}
return b;
}
What does it do: The function makes an empty array first, then checks the parameter member by member, if the i'th member is an Array, it calls itself with that member as a parameter, and adds the result to its temporary array, otherwise it's just pushing next member of a into the temporary array. So, to make your allIntro a flat array, you call allIntro=flatten(allIntro) after declaring it as you did. The same for other arrays.