Create multidimensional arrays ( n-dimensions ) - arrays

I have a string : a - b - c and I would like to create a array.
A [] >> B [] >> C []
var f:Array = "a-b-d".split('-');
var tree:Array = new Array;
for (var i:Number=0; i < f.length ; i++)
{
var o:Object = new Object
o.name = f[i];
o.path = f.slice(0,i);
o.isDirectory = (i == f.length)? false :true ;
}
I would like this
var x:Array = new Array(new Array(new Array()));
Is this the right way? Or how could I do?

Yes, you can create a multi-dimensional array within arrays. It might be useful to create an "Object" instead, and have Array as collections for those objects, given your data model. And it may be useful to create helper methods to search, retrieve, update, and delete items within that structure.
The problem is how is your string structured? Is it only 3 levels deep? This is untested code, and based on assumptions you've laid out that your string structure is only a set level deep.
Here's how, using your code:
var f:Array = "a-b-c".split('-');
// create first dimension of arrays (tree)
var tree:Array = new Array();
var secondTree:Array = new Array();
var thirdTree:Array = new Array();
secondTree.push(thirdTree);
tree.push(secondTree);
// create second dimension of arrays (tree)
for (var i:int=0; i < f.length; i++)
{
var o:Object = new Object
o.name = f[i];
o.path = f.slice(0,i);
o.isDirectory = (i == f.length)? false : true;
if(i%3 == 0) {
thirdTree.push(o);
} else if(i%2 == 0) {
secondTree.push(o);
} else {
tree.push(o);
}
}

Related

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
}
}

Remove movieClips using array list?

I've a array of list and created image place holder with the array objects name (Example: myArray[a,b]) and loaded images from there, having array list as folder name.
And finally created a movieClip to load on them and display in stage.
Now I want to remove them calling the same array list.
Need help here...
My code below:
for (var l: int = 0; l < ListArray.length; l++) {
var BookName: MovieClip = new bookThumb();
trace("\n[" + l + "]: " + ListArray[l]);
ImageFoldername = ListArray[l];
var bookImagePath: String = "file://" + File.userDirectory.nativePath.toString() + "/Books/" + ImageFoldername + "/Images/Icon.png";
trace(bookImagePath);
var ImagePlacer: Loader = new Loader;
var ImageURL: URLRequest = new URLRequest(bookImagePath);
ImagePlacer.load(ImageURL);
BookName.addChild(ImagePlacer);
BookName.name = ImageFoldername
addChild(BookName)
BookName.x = FirstBook_x;
BookName.y = FirstBook_y;
BookName.buttonMode = true;
BookName.mouseChildren = false;
BookName.addEventListener(MouseEvent.CLICK, IconSelected);
BookName.alpha = .8
BookName.addEventListener(MouseEvent.MOUSE_OVER, IconMouseOver);
BookName.addEventListener(MouseEvent.MOUSE_OUT, IconMouseOut);
FirstBook_x = FirstBook_x + 250;
}
Because you assign the ImageFoldername to each MovieClip's name property, you can use getChildByName to find them and remove them:
(Note: convention in AS3 is to use UpperCamelCase for classes, and lowerCamelCase for variables and functions. I've written the code below following this convention. )
for (var i:int = 0; i < listArray.length; i++) {
var imageFolderName:String = listArray[i];
var bookThumb:BookThumb = getChildByName(imageFolderName) as BookThumb;
if (bookThumb) {
removeChild(bookThumb);
}
}
Another way you can handle it is to add each book thumb into a list:
var bookThumbs:Array = [];
for (var i:int = 0; i < listArray.length; i++) {
var bookThumb:Bookthumb = new BookThumb();
bookThumbs.push(bookThumb);
// ...
}
Then to remove them all:
for each (var bookThumb:BookThumb in bookThumbs) {
removeChild(bookThumb);
}
bookThumbs.length = 0;
But probably the easiest way to remove them all would be to simply put them all in a single container and later use removeChildren() to remove them all:
var container:Sprite = new Sprite();
addChild(container);
for (var i:int = 0; i < listArray.length; i++) {
var bookThumb:Bookthumb = new BookThumb();
container.push(bookThumb);
// ...
}
// when you want to remove them all:
container.removeChildren();

getting specific values from an object

(I am working with Angular but this is not an angular specific problem).I have a json object that i am trying to disect. I've been trying to get my head around this and have come up with a complicated script with nested for loops that isn't working. The object consists of 3 arrays. The first array is an array of fieldnames. The third array is an array of arrays that correspond to the field names like so:
object = {"fields" : [array], "type" : [array], "values" : [array]}
where:
fields = ["user","bananas","pies","apples","pears","mangos","date"]
values = [["Bongo","12","2","1","2","4","05-02-2015"], ["Mongo","12","23","15","22","43","05-02-2015"], ["Congo","15","32","21","23","44","06-02-2015"]]
What i want to do is count the amount of fruit that all users had on a specific date. for instance i want to know how many bananas all users had on "06-02-2015".
I can post my code, but i think that would only work confusing as it's probably wrong and redundant.
update:
I've tried the filter but can't get it to work because the values inside object.values don't have a name. So i think it should be something like this:
var fruits = $filter('filter')(object.value, {???[6] : "2015-04-29 00:00:00"}, true);
I'm not sure what the ??? should be.
solved:
simply removing the name did the trick.
var fruits = $filter('filter')(object.value, "2015-04-29 00:00:00", true);
This script should group the values by date:
var fields = ["user","bananas","pies","apples","pears","mangos","date"];
var values = [["Bongo","12","2","1","2","4","05-02-2015"], ["Mongo","12","23","15","22","43","05-02-2015"], ["Congo","15","32","21","23","44","06-02-2015"]];
var result = {};
for (var j = 0; j < values.length; j++) {
if (!result.hasOwnProperty(values[j][fields.length - 1]))
result[values[j][fields.length - 1]] = {};
for (var i = 1; i < fields.length - 1; i++) {
if (!result[values[j][fields.length - 1]][fields[i]])
result[values[j][fields.length - 1]][fields[i]] = parseInt(values[j][i], 10);
else
result[values[j][fields.length - 1]][fields[i]] += parseInt(values[j][i], 10);
}
}
console.log(result);
What you need is a filter:
var fruits = $filter('filter')(object, {date: $choosenDate}, true);
Then, if you want to split fruit by type, you can use angular.forEach to iterate on the nev fruits var
This would be a lot simpler if the structure of the arrays wasn't bananas, so to speak.
var fields = ["user","bananas","pies","apples","pears","mangos","date"];
var values = [["Bongo","12","2","1","2","4","05-02-2015"], ["Mongo","12","23","15","22","43","05-02-2015"], ["Congo","15","32","21","23","44","06-02-2015"]];
var date, dataArray, dateIndex = (fields.length - 1),
dates = {};
for (var i = 0; i < values.length; i++) {
dataArray = values[i];
date = dataArray[dateIndex];
dates[date] = dates[date] || {};
for (j = 1; j < fields.length - 1; j++) {
dates[date][fields[j]] = dates[date][fields[j]] || 0;
dates[date][fields[j]] += Number(dataArray[j]);
}
}
console.log(dates);

For Loop Creation of new instance of Array in ActionScript 3

Is there any way to create instances of array in a for loop?
Here's my code...
var recArrCon1:Array = new Array(50);
var recArrCon2:Array = new Array(50);
var recArrCon3:Array = new Array(50);
var recArrCon4:Array = new Array(50);
var recArrCon5:Array = new Array(50);
var recArrCon6:Array = new Array(50);
var recArrCon7:Array = new Array(50);
var recArrCon8:Array = new Array(50);
I want to make declaration in a dynamic way by a for loop.
Thanks in advance.
By the way, I'm using AS3
Edit: The answer is (from Barış Uşaklı):
var recArrCons:Object = {};
for(var i:int=1; i<=8; i++)
{
recArrCons["recArrCon" + i] = new Array(50);
}
trace(recArrCons.recArrCon4); // 4th array
Make the class containing this code dynamic then you can create the names dynamically.
for(var i:int=1; i<=8; i++)
{
this["recArrCon" + i] = new Array(50);
}
trace(this.recArrCon4); // 4th array
Or you can store them in an Object like :
var recArrCons:Object = {};
for(var i:int=1; i<=8; i++)
{
recArrCons["recArrCon" + i] = new Array(50);
}
trace(recArrCons.recArrCon4); // 4th array
I wouldn't create instances of Array the way you are, it's very messy. I suggest using a list of arrays like this:
var arrays:Vector.<Array> = new <Array>[];
for(var i = 0; i < 8; i++)
{
arrays.push(new Array(50));
}
Where you would access an array like this:
var inner:Array = arrays[2];
And values of the arrays using [x][y]:
trace(arrays[0][0]);

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.

Resources