Loading array of display objects using shared objects in action script 3.0 - arrays

I'm trying to load an array that contain some display objects, the program lets me to populate the array with circles and save them to a shared object, then, I can trace the content of my array using the load button. The problem is that i can't load the array after that I restart my program. It traces me this message:"objects loaded: ,,,"
This is the code:
var SO:SharedObject=SharedObject.getLocal("myFile", "/");
var arr:Array=new Array();
var counter:Number=-1;
addBtn.addEventListener(MouseEvent.CLICK, addObjects);
saveBtn.addEventListener(MouseEvent.CLICK, saveObjects);
loadBtn.addEventListener(MouseEvent.CLICK, loadObjects);
function addObjects(event:Event) {
counter++;
var circle:circleClip=new circleClip();
arr.push(circle);
trace("current object: "+arr[counter]);
}
function saveObjects(event:Event) {
SO.data.arrSaved=arr;
SO.flush();
trace("objects saved: "+SO.data.arrSaved);
}
function loadObjects(event:Event) {
var arrLoaded:Array=new Array();
arrLoaded=SO.data.arrSaved;
trace("objects loaded: "+arrLoaded);
}

You are to understand MVC pattern approach: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
You need to separate data from the code that visualizes things out of these data, and store data only. Something like:
// Lets say this Array contains a list of your circle objects.
var Curcus:Array;
// Storage.
var SO:SharedObject = SharedObject.getLocal("myFile", "/");
function saveCircus():void
{
var aList:Array = new Array;
aList.length = Circus.length;
for (var i:int = 0; i < Curcus.length; i++)
{
// Get an object.
var aCircle:Sprite = Curcus[i];
// Record its properties you want to store.
var anEntry:Object =
{
"x":aCircle.x,
"y":aCircle.y,
"scaleX":aCircle.scaleX,
"scaleY":aCircle.scaleY
};
// Store the entry.
aList[i] = anEntry;
}
// Store and save data.
SO.data.arrSaved = aList;
SO.flush();
}
function loadCircus():void
{
// Retrieve saved data.
var aList:Array = SO.data.arrSaved;
// Make it empty data if there are none.
if (!aList) aList = new Array;
Circus = new Array;
Curcus.length = aList.length;
for (var i:int = 0; i < aList.length; i++)
{
// Get one entry.
var anEntry:Object = aList[i];
// Create a new item. BTW, naming classes with the
// lowercase first letter is the 8th cardinal sin.
var aCircle = new CircleClip;
// Restore saved properties.
aCircle.x = anEntry['x'];
aCircle.y = anEntry['y'];
aCircle.scaleX = anEntry['scaleX'];
aCircle.scaleY = anEntry['scaleY'];
// Add to display list.
addChild(aCircle);
// Keep it for the future reference/saving.
Curcus[i] = aCircle;
}
}

Related

remove common elements from two arrays in appscript?

I have a google sheet. I am try to get all tab names in to array. I used this code.
function allTabNames() {
try{
var out = new Array();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for (var i =0; i<sheets.length; i++) out.push([sheets[i].getName()]);
Logger.log(out);
Logger.log(out.length);
return out
}
catch (er){
Logger.log(er);
}
}
It's working correctly. Now I want to remove some tab names. I created a new array using the tab names I want to remove.
var duparray = ["Sheet1", "newRoad147", "Sheet2", "Sheet3", "Sheet4","Sheet5", "Sheet6"];
When I run the first mentioned code I will get this. The array "out".
[[Sheet1], [newRoad147], [Sheet2], [Sheet3], [Sheet4], [Sheet5], [Sheet6], [Sheet7], [AddData], [WCO069], [WCO065], [WCO149], [WCO141], [WCO158], [BarChart], [Sheet11]]
I am trying to remove the common element in these two arrays. For that I used the following code. But it did not go well.
function allTabNames() {
try{
var out = new Array();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for (var i =0; i<sheets.length; i++) out.push([sheets[i].getName()]);
Logger.log(out);
Logger.log(out.length);
//return out
var duparray = ["Sheet1", "newRoad147", "Sheet2", "Sheet3", "Sheet4","Sheet5", "Sheet6"];
var outx = out.filter( function( el ) {
return duparry.indexOf( el ) < 0;
} );
}
catch (er){
Logger.log(er);
}
Logger.log(outx);
}
The order of these tabs can be changed. That is why I try to remove the element using the specific names of the elements in the array. Then we hope to create a dropdown list of elements in this new array using data validation.
Get Sheet names and omit not included
function getTabName() {
const ss = SpreadsheetApp.getActive();
const nincl = ['Sheet1','Sheet2'];//not included
const shts = ss.getSheets().filter(sh => !~nincl.indexOf(sh.getName())).map(sh => sh.getName());
ss.getSheetByName('Sheet5').getRange("C5").setDataValidation(SpreadsheetApp.newDataValidation().requireValueInList(shts,true).build());
return shts;
}

Filter one array using a 2nd array, and display the results on a spreadsheet

----- BACKGROUND ----- In Google Sheets/Apps Script, I'm trying to move some transaction data from one sheet and organize it on a different sheet with subtotal rows for each customer account (called "Units") with a grand total at the bottom.
I have the transactions organized in an array of objects as key:value pairs ("transactions", the keys are headers, some values are strings, others are numbers), and I have the units in a 2nd array called "unitList". I want to iterate through each element in the unitList array, and pull each transaction with a matching unit onto my "targetSheet", then append a subtotal row for each unit.
----- UPDATE 10/7/2018 3:49PM EST -----
Thanks to everyone for your input - I took your advice and ditched the library I was using and instead found better getRowsData and appendRowsData functions which I put directly in my code project. This fixed the array filter problem (verified by logging filterResults), BUT, now when I call appendRowsData(), I get this error:
The coordinates or dimensions of the range are invalid. (line 73, file "Display Transactions")
Line 73 is the line below, in the appendRowsData function. Any help on how to fix this would be greatly appreciated.
var destinationRange = sheet.getRange(firstDataRowIndex, 1, objects.length, 9);
Here's my project in it's entirety thus far:
function displayTransactions() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Label each sheet
var dashboard = ss.getSheetByName('Dashboard');
var unitsSheet = ss.getSheetByName('Unit Ref Table');
var transactionsSheet = ss.getSheetByName('Transactions Ref Sheet');
var targetSheet = ss.getSheetByName('Target Sheet');
// Returns true if the cell where cellData was read from is empty.
// Arguments:
// - cellData: string
function isCellEmpty(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
// Define function that converts arrays into JSON
// For every row of data in data, generates an object that contains the data.
// Names of object fields are defined in keys.
// Arguments:
// - data: JavaScript 2d array
// - keys: Array of Strings that define the property names for the objects to create
function getObjects(data, keys) {
var objects = [];
for (var i = 0; i < data.length; ++i) {
var object = {};
var hasData = false;
for (var j = 0; j < data[i].length; ++j) {
var cellData = data[i][j];
if (isCellEmpty(cellData)) {
continue;
}
object[keys[j]] = cellData;
hasData = true;
}
if (hasData) {
objects.push(object);
}
}
return objects;
}
// Define function that pulls spreadsheet data into arrays, then converts to JSON using getObjects function
function getRowsData(sheet) {
var headersRange = sheet.getRange(1, 1, 1, sheet.getLastColumn());
var headers = headersRange.getValues()[0];
var dataRange = sheet.getRange(sheet.getFrozenRows()+1, 1, sheet.getLastRow(), sheet.getLastColumn());
return getObjects(dataRange.getValues(), headers);
}
// Define function appendRowsData that uses getLastRow to fill in one row of data per object defined in the objects array.
// For every Column, it checks if data objects define a value for it.
// Arguments:
// - sheet: the sheet object where the data will be written
// - objects: an array of objects, each of which contains data for a row
function appendRowsData(sheet, objects) {
var headersRange = sheet.getRange(7, 1, 1, 9);
var firstDataRowIndex = sheet.getLastRow() + 1;
var headers = headersRange.getValues()[0];
var data = [];
for (var i = 0; i < objects.length; ++i) {
var values = []
for (j = 0; j < headers.length; ++j) {
var header = headers[j];
values.push(header.length > 0 && objects[i][header] ? objects[i][header] : "");
}
data.push(values);
}
var destinationRange = sheet.getRange(firstDataRowIndex, 1, objects.length, 9);
destinationRange.setValues(data);
}
// Call getRowsData on transactions sheet
var transactions = getRowsData(transactionsSheet);
// Get array of units
var unitList = unitsSheet.getRange("B2:B").getValues();
// Iterate through the unitList and pull all transactions with matching unit into the target sheet
for (var i=0; i < unitList.length; i++) {
var subTotal = 0;
var grandTotal = 0;
var filterResults = transactions.filter(function(x) {
return x['Unit'] == unitList[i];
})
Logger.log(filterResults); // This brings the correct results!
// Display matching transactions
appendRowsData(targetSheet, filterResults);
// Grand total at the bottom when i=units.length
}
}

ActionScript 3 Can't Add and Remove item from Array

I'm working on a shopping list app and i'm having issue's removing and adding an item within the array.
I have an output_txt.text and input_txt.text with three buttons add_btn, remove_btn, and clear_btn. Inside my list (output) I have items of "Bread, Dog Food, Eggs, Hamburger, Milk". I want to be able to add items to the list and sort them alphabetically.
When I add an item it sorts it alphabetically, however when I try to add another item it just replaces the last item I entered.
When I want to clear an item I want to be able to copy the item from the list and place it in the input textbox and click the remove btn to remove it, but when I do this it only removes the second item and then places it to the bottom of the list.
(The totalItems_txt.text is the total number of items I add and remove from the list.)
Here's my code:
clear_btn.addEventListener(MouseEvent.CLICK, ClearList);
function ClearList(e:MouseEvent):void {
output_txt.text = "";
totalItems_txt.text = "0";
}
addItem_btn.addEventListener(MouseEvent.CLICK, AddItem);
function AddItem(e:MouseEvent):void {
var newItems:Array = ["Bread", "Dog Food", "Eggs", "Hamburger", "Milk"];
newItems[0] = "Bread";
newItems[1] = "Dog Food";
newItems[2] = "Eggs";
newItems[3] = "Hamburger";
newItems[4] = "Milk";
newItems[5] = input_txt.text;
newItems.sort(Array.CASEINSENSITIVE);
input_txt.text = "";
output_txt.text = "";
for (var i:int = 0; i < newItems.length; i++){
output_txt.appendText(newItems[i] + "\n");
}
totalItems_txt.text = newItems.length.toString();
}
remove_btn.addEventListener(MouseEvent.CLICK, RemoveItems);
function RemoveItems(e:MouseEvent):void {
var items:Array = ["Bread", "Dog Food", "Eggs", "Hamburger", "Milk"];
items[0] = "Bread";
items[1] = "Dog Food";
items[2] = "Eggs";
items[3] = "Hamburger";
items[4] = "Milk";
items[5] = input_txt.text;
output_txt.text = "";
items.splice(1,1);
for (var i:int = 0; i < items.length; i++){
output_txt.appendText(items[i] + "\n");
}
totalItems_txt.text = items.length.toString();
}
It's easier to identify the cause of the problem if you provide a complete and verifiable example, however, at the heart of your issue is an understanding of the Array methods:
splice(startIndex:int, deleteCount:uint), for removing items.
push(... args), for adding items.
If you explicitly reference newItems[0] thru [5], then you'll only ever affect entries 0 - 5, however, push is useful since it simply adds it to the end of your array. Conversely, you could use either splice (to specifically target a certain index), or pop() (which removes the last element from an array) to delete items from your array.
The other problem is that your arrays are local. Because you're recreating them every time you call RemoveItems or AddItem, you'll never save your changes. So, move it outside of those functions, and it'll be saved between clicks.
I've reworked your code with changes, and added supplemental code for the missing UI code you didn't provide. You can run this in a new .fla file and it will work as intended.
import flash.text.TextField;
import flash.events.KeyboardEvent;
import flash.display.Sprite;
var items:Array = ["Bread", "Dog Food", "Eggs", "Hamburger", "Milk"];
function addItem(e:MouseEvent):void {
if (input_txt.text != "") { // Assuming we having something in the input_txt,
items.push(input_txt.text); // add it to the end of our items array
input_txt.text = "";
updateOutput();
}
}
function removeItems(e:MouseEvent):void {
items.splice(0,1);
updateOutput();
}
function clearList(e:MouseEvent):void {
items = []; // empty our list by replacing it with a new one.
output_txt.text = "";
totalItems_txt.text = "0";
}
function updateOutput():void {
items.sort(Array.CASEINSENSITIVE);
output_txt.text = "";
for (var i:int = 0; i < items.length; i++){
output_txt.appendText(items[i] + "\n");
}
totalItems_txt.text = "Total: " + items.length;
}
/* Supplemental UI Creation */
var addItem_btn:Sprite = new Sprite();
addItem_btn.graphics.beginFill(0xa1FFa1,1);
addItem_btn.graphics.drawRect(0,0,100,25)
addChild(addItem_btn);
addItem_btn.addEventListener(MouseEvent.CLICK, addItem);
var clear_btn:Sprite = new Sprite();
clear_btn.graphics.beginFill(0xa1a1a1,1);
clear_btn.graphics.drawRect(0,0,100,25)
addChild(clear_btn);
clear_btn.x = 101;
clear_btn.addEventListener(MouseEvent.CLICK, clearList);
var remove_btn:Sprite = new Sprite();
remove_btn.graphics.beginFill(0xFFa1a1,1);
remove_btn.graphics.drawRect(0,0,100,25)
addChild(remove_btn);
remove_btn.x = 202;
remove_btn.addEventListener(MouseEvent.CLICK, removeItems);
var input_txt:TextField = new TextField();
addChild(input_txt);
input_txt.type = "input";
input_txt.text = "input_txt";
input_txt.y = 50;
var output_txt:TextField = new TextField();
addChild(output_txt);
output_txt.text = "output_txt";
output_txt.y = 50;
output_txt.x = 101;
var totalItems_txt:TextField = new TextField();
addChild(totalItems_txt);
totalItems_txt.text = "totalItems_txt";
totalItems_txt.y = 50;
totalItems_txt.x = 202;
All you had to do is declare your array as public and then add just the values to the array by using push(). when you sort the actual index of the array still remains , but the displayed items index will be different ,

Splice array within array

How can I splice an array within another array?
I'm trying to create a game for kids in my class. Some kind of a trivia history question creator. How to splice the MasterArray so that I would get rid of sub-arrays (Hard-England and Medium-England) within the allEnglandArray. Because the "MasterArray.splice()" seem to be affecting - splicing only the allEngland array, or the allFrance array. But I need to get rid of those sub-arrays...
My code:
var Easy-England:Array = ["item1","item2","item3","item4","item5"];
var Medium-England:Array = ["item6","item7","item8"];
var Hard-England:Array = ["item9","item10"];
var allEngland:Array = [Easy-England,Medium-England,Hard-England];
var Easy-France:Array = ["item11","item12","item13","item14","item15"];
var Medium-France:Array = ["item16","item17","item18"];
var Hard-France:Array = ["item19","item20"];
var allFrance:Array = [Easy-France,Medium-France,Hard-France];
// the list of countries goes on and on and on... (Italy, Hungary, etc.)
var allStuff:Array = [allEngland, allFrance, etc.];
var MasterArray:Array;
// FUNCTIONS
// clear MasterArray - first I clear out completely the MasterArray
function clearMasterArray():void
{
MasterArray.splice(0);
}
// update MasterArray - than I fill the MasterArray with data according to checkBoxes
function updateMasterArray():void
{
for (var i:int = 0; i<checkBoxBlock.myCheckBoxes.length; i++)
{
if (checkBoxBlock.myCheckBoxes[i].selected)
{
MasterArray.push(allStuff[i]);
}
}
}
// splice MasterArray - last thing I do is splice the items according to student's proficiency level, referred to as "studentPL".
function spliceMasterArray():void
{
if (studentPL == 1)
{
for (var i:int = 0; i<allStuff.length; i++)
{
allStuff[i].splice(5,5);
}
}
if (studentPL == 2)
{
for (var i:int = 0; i<allStuff.length; i++)
{
allStuff[i].splice(8,2);
}
}
if (studentPL == 3)
{
for (var i:int = 0; i<allStuff.length; i++)
{
trace("no need to splice");
}
}
}
And after this I call those functions in another function in this order...
function creatorFunction():void
{
clearMasterArray();
updateMasterArray();
spliceMasterArray();
}
Instead of:
var allEngland:Array = [Easy-England,Medium-England,Hard-England];
try this:
var allEngland:Array = Easy-England.concat(Medium-England, Hard-England);
This way you will have a 'flat' array (no sub-arrays), so it will be easier to deal with.

calling swf with an array, not working with my string in flash

I'm trying to get my SWF loader to work with an array so I can call my swf files via one code, using buttons.
This is the problem I am getting:
Scene 1, Layer 'actions', Frame 2, Line 68 1067: Implicit coercion of a value of type Array to an unrelated type String.
I am not too good with arrays, or strings, or coding tbh, i'm not too sure what the problem is, I understand it, my array and my string don't work together,basically, but I don't know how to fix it, if it can be fixed/work with the code I am using.
just some help and being pointed in the right direction would be a treat
var swfList:Array = ["imagegallery.swf", "videoplayer.swf"];
var SWFLoader = new Loader;
var SWFRequest = new URLRequest (swfList) ;
SWFLoader.load (SWFRequest) ;
function loadSWF(file:String, container:MovieClip=null):void
{
if(container == null) container = MovieClip(root);
if(SWFLoader != null)
{
if(SWFLoader.parent) SWFLoader.parent.removeChild(SWFLoader);
}
addChild (SWFLoader);
}
vidPlayer_btn.addEventListener (MouseEvent.CLICK, goVidPlayer);
function goVidPlayer (e:MouseEvent):void
{
loadSWF("videoplayer.swf");
}
imageGallery_btn.addEventListener(MouseEvent.CLICK, goImageGallery);
function goImageGallery(e:MouseEvent):void
{
loadSWF("imagegallery.swf");
}
To access items within an array use this format:
var SWFRequest = new URLRequest(swfList[i]);
Where i is the position in array (starting at zero).
For instance:
var SWFRequest = new URLRequest(swfList[0]);
gives the same result as:
var SWFRequest = new URLRequest("imagegallery.swf");
Did away with the array but still "have one code for both buttons instead of two separate codes".
// Looks unnecessary
// var swfList:Array = ["imagegallery.swf", "videoplayer.swf"];
// Transfer inside loadSWF()
// var SWFRequest = new URLRequest (swfList); // needs a url String parameter
// SWFLoader.load (SWFRequest);
var SWFLoader = new Loader(); // Don't forget the parenthesis
vidPlayer_btn.addEventListener (MouseEvent.CLICK, goVidPlayer);
imageGallery_btn.addEventListener(MouseEvent.CLICK, goImageGallery);
function goVidPlayer (e:MouseEvent):void
{
loadSWF("videoplayer.swf");
}
function goImageGallery(e:MouseEvent):void
{
loadSWF("imagegallery.swf");
}
function loadSWF(file:String, container:MovieClip=null):void
{
// What for?
// if(container == null) container = MovieClip(root);
if(SWFLoader != null)
if(SWFLoader.parent)
SWFLoader.parent.removeChild(SWFLoader);
var SWFRequest = new URLRequest (file) ;
SWFLoader.load (SWFRequest);
addChild (SWFLoader);
}

Resources