How to separate the json data to push to spreadsheet? - arrays

Here is the code so far. Keep in mind the data i am passing to the function has already been parsed and stringified.
Here is my code so far. I just need to know how to push the data to the rows array and not how to move to a spreadsheet yet.
I keep getting an empty array: [17-03-29 05:07:48:351 PDT] [[null]]
function pullJSON(data) {
var rows = [];
for (i = 0; i < data.length; i++) {
var dataS = data[i];
rows.push([dataS.id]);
Logger.log(rows);
}
Here is the data that being passed to the function

Related

I am trying to create multiple loops but if one loop returns null it doesn't run the rest of the loop. How do I get around this?

I have multiple for loops in one code, as I am trying to collect data based off identifier "Y". There are some sheets that do not have identifier "Y" and those sheets always cause my script to stop running as the error cannot find the length in that specific for loop since there is none.
How do I get around this? I've tried if/else in everywhere I think would work and it's not working.
I've tried if/else statements and breaks but I must not be putting them in the right spot.
var VDSLr = VDSL.getRange('A:AS');
var VDSLraw = VDSLr.getValues();
var VDSLdata = []
for (var i = 0; i< VDSLraw.length ; i++){
if (VDSLraw[i][44] == "Y")
{
VDSLdata.push(VDSLraw[i])
}
Pull.getRange(Pull.getLastRow()+1,1, VDSLdata.length,
VDSLdata[0].length).setValues(VDSLdata);
}
var ITr = IT.getRange('A:AS');
var ITrawdata = ITr.getValues();
var ITd= []
for (var i = 0; i< ITrawdata.length ; i++){
if(ITrawdata[i][44] == "Y")
{
ITd.push(ITrawdata[i])
}
Pull.getRange(Pull.getLastRow()+1,1, ITd.length,
ITd[0].length).setValues(ITd);
}
**Edit: it won't let me post a picture of my error yet. Here's a few
examples though:
Error (1):**
var VDSLr = VDSL.getRange('A:AS');
var VDSLraw = VDSLr.getValues();
var VDSLdata = []
for (var i = 0; i< VDSLraw.length ; i++){
if (VDSLraw[i][44] != "Y")**continue**;
if (VDSLraw[i][44] == "Y");
{
VDSLdata.push(VDSLraw[i])
}
}
Pull.getRange(Pull.getLastRow()+1,1, VDSLdata.length,
VDSLdata[0].length).setValues(VDSLdata);
var ITr = IT.getRange('A:AS');
var ITrawdata = ITr.getValues();
var ITd= []
for (var i = 0; i< ITrawdata.length ; i++){
if (ITrawdata[i][44] != "Y")continue;
if (ITrawdata[i][44] == "Y")
{
ITd.push(ITrawdata[i])
}
}
Pull.getRange(Pull.getLastRow()+1,1, ITd.length,
ITd[0].length).setValues(ITd);
So if I put a continue here, it won't read the length. Error code is "Cannot read property "length" from undefined. Which I know is correct. This is what I'm trying to bypass. "VDSL" is a sheet that normally does not have what I am looking for. But since it won't find the length it won't continue to sheet "IT."
I have also moved around the continues to different spots, and even a break (in the same spot as continue) but my combinations seem to provide a never ending loop of the same info.
The other attempt is with if else statements. When I use those I get a synthax error. On this error(2) I've tried:
if (VDSLraw[i][44] == "Y")
{//code here}
else if (VDSLraw[i][44] != "Y"){break};
I feel like I'm making this more complicated than it is, should be a simple if/then statement but since I have to pull the data and compile it to one sheet the for loop is the best way to go. Just can't figure out the last piece. I could do them separately but that's my last resort. There's 12 sheets, so clicking 12 scripts each time I need to do this doesn't seem efficient.
as soon as you provided limited information about your data I made some assumptions, I hope it matches your needs.
function getY_Data(){
// get the current Spreadsheet;
var currentSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// get all tabs on the file, so you wont need to keep track of how many tabs you have
var tabsArray = currentSpreadsheet.getSheets();
var resultsSheet = currentSpreadsheet.getSheetByName("results");
var currentSheetValues;
var collected_Y_Rows = [];
// iterate over all tabs
tabsArray.forEach(function(tabObject,index){
// skip the results tab
if(tabObject.getName() === "results"){ continue; }
// set the current sheet data to currentSheetValues variable
currentSheetValues = tabsArray[0].getDataRange().getValues();
// Im considering that all your sheets has the same row size
currentSheetValues.forEach(function(row,index){
if(row[44] == "Y"){
collected_Y_Rows.push(row);
}
});
});
// if it hasnt find any row with "Y" it won't clear the "results" tab or try do add empty data to the "results" sheet
if(collected_Y_Rows.length === 0){
return;
}
// clear the current values and formats
resultsSheet.clear();
// append new data starting on row 1 and col 2;
// Im considering that all your sheets has the same row size;
// if the sheets tabs has different sizes of data (columns) it will throw an error because when using the range.setValues(collected_Y_Rows),
// all rows on "collected_Y_Rows" mas have the same size;
resultsSheet.getRange(1, 1, collected_Y_Rows.length, collected_Y_Rows[0].length).setValues(collected_Y_Rows);
}

Get two arrays, compare and remove duplicates in Google Apps Script

I have got two lists on a google spreadsheet: 'Existing Companies' and 'New Companies'.
I would like to compare the two and find out which unique entries in 'New Companies' do not exist in 'Existing Companies', get those entries and eliminate from 'New Companies' all other entries.
I have made the following script to do it:
function grabNewCompanies() {
// grab existing companies list from sheet into an array
var sh = SpreadsheetApp.openById("sheetID").getSheetByName("sheetName")
var row = sh.getDataRange().getLastRow()
var existingCompanies = sh.getRange(2,1,row - 1,1).getValues()
Logger.log(existingCompanies)
//grab new companies added
var sh = SpreadsheetApp.openById("sheetID").getSheetByName("sheetName")
var row = sh.getDataRange().getLastRow()
var newCompanies = sh.getRange(2,4,row - 1, 1).getValues()
Logger.log(newCompanies)
var array = [];
for(i=0; i<newCompanies.length; i++) {
for(j=0; j<existingCompanies.length; j++) {
if(newCompanies[i][0] !== existingCompanies[j][0]) {
array.push([newCompanies[i][0]]);
}
Logger.log(array)
}
I have ran this script but it has failed.
The two arrays (existingCompanies and newCompanies) are returned correctly.
However, the comparison between the two does not seem to be working: it always returns the first element of the newCompanies array, regardless of whether it exists in existingCompanies.
Also, I am unsure about how to ensure that the values pushed into array are not duplicated if newCompanies contains more than one entry which does not exist in existingCompanies.
Thank you.
You want to retrieve the difference elements between existingCompanies and newCompanies. If my understand for your question is correct, how about this modification? I think that there are several solutions for your situation. So please think of this as one of them.
Modification points:
In the case that your script is modified, it picks up an element from newCompanies and it checks whether that is included in existingCompanies.
If that picked element is not included in existingCompanies, the element is pushed to array. In this modification, I used true and false for checking this.
This flow is repeated until all elements in newCompanies are checked.
Modified script 1:
When your script is modified, how about this?
From:
var array = [];
for(i=0; i<newCompanies.length; i++) {
for(j=0; j<existingCompanies.length; j++) {
if(newCompanies[i][0] !== existingCompanies[j][0]) {
array.push([newCompanies[i][0]]);
}
}
}
To:
var array = [];
for(i=0; i<newCompanies.length; i++) {
var temp = false; // Added
for(j=0; j<existingCompanies.length; j++) {
if(newCompanies[i][0] === existingCompanies[j][0]) { // Modified
temp = true; // Added
break; // Added
}
}
if (!temp) array.push([newCompanies[i][0]]); // Modified
}
Logger.log(array)
Modified script 2:
As other patterns, how about the following 2 samples? The process cost of these scripts are lower than that of the script using for loop.
var array = newCompanies.filter(function(e) {return existingCompanies.filter(function(f) {return f[0] == e[0]}).length == 0});
Logger.log(array)
or
var array = newCompanies.filter(function(e) {return !existingCompanies.some(function(f) {return f[0] == e[0]})});
Logger.log(array)
If I misunderstand your question, please tell me. I would like to modify it.

What is the best effective way to collect data from a table using protractor?

What is the best effective way to collect data from a table using protractor.
I collecting the data shown in the code below and it is taking 20-30 seconds for 10 rows.
The buildStr counter is for creating a object for every row, 8 is the number of columns.
row = {};
gridRows = [];
element.all(by.css('#contenttableGrid div[role="gridcell"] div')).each(function(element){
element.getText().then(function(text){
row[headerName[buildStr]] = text;
buildStr++;
if(buildStr === 8){
buildStr = 0;
gridRows[rowCounter] = row;
rowCounter++;
row = {};
}
});
});
One way to speed it up that I see is to extract all the data right on the page by injecting script on it. It could be done with the help of browser.executeScript() (docs). In your sample Protractor has to make a request to the browser any time you call getText(), nubmer of calls it makes = number of cells in your table. But using browser.executeScript() it will make one call and do all the stuff in the browser, which can be really fast. Then you can simply return this data back to a test spec and use it via Promises.
var headerName = {};
// I assume that this variable holds names for headers
// you can pass data from test spec to injected script as arguments (below)
// promise will be resolved with the value you return from `executeScript`
var promise = browser.executeScript(function (headerName) {
// all the stuff inside this function happens on your page under test
// it is not a Protractor environment
var buildStr = 0;
var rowCounter = 0;
var row = {};
var gridRows = [];
var cells = document.querySelectorAll('#contenttableGrid div[role="gridcell"] div');
for (var i = 0, l = cells.length; i < l; i++) {
var text = cells[i].textContent;
// `headerName` object is passed as an argument from test spec
row[headerName[buildStr]] = text;
buildStr++;
if (buildStr === 8) {
buildStr = 0;
gridRows[rowCounter] = row;
rowCounter++;
row = {};
}
}
// return all collected data back to test spec
return gridRows;
}, headerName); // pass helper object from test spec to injectable function
promise.then(function (gridData) {
console.log(gridData); // result of computations
});
Make sure to read docs for browser.executeScript() if you want to use it, because it has a lot of specific moments.

AS2 push to array outside of clip does nothing

was wondering if someone could show me what I'm doing wrong here.
I have some old AS2 flash code I'm trying to get working.
First I create a few arrays in frame 1 of the main timeline like so-
var typeArr:Array = new Array();
for (var i:Number = 1; i < 5; i++)
{
_root.typeArr[i] = "data goes here";
}
Then I have a movieclip dynamically attached on the main stage that when clicked appends one of the arrays we created by pushing the string 'foo' to it-
stop();
_root.myType=3;//this can be any of our array numbers
this.onPress=function(){
var foo:String="test";
_root.typeArr[_root.myType].push(foo);
trace(_root.typeArr[_root.myType]);
}
Where _root.typeArr[_root.myType] is the array name and number _root.typeArr3, but pushing the data does not work and returns nothing.
However, if I test it directly using-
_root.typeArr[_root.myType]=foo;
It will store the data once (_root.typeArr3=test), so I can't see why it won't push to that array as multiple elements each time like- "test,test,test"
It's driving me crazy.
Thanks! :)
_root.typeArr[_root.myType] is equal to "data goes here" so you are pushing string to a string, which doesn't work.
If you would like to append the new string, you should do something like:
_root.typeArr[_root.myType]+=foo;
and you will get: data goes heretest
If you have different data structure instead of "data goes here" the key may lie in the format of this data.
var typeArr:Array = new Array();
// 'i' must start from 0 because the first element is typeArr[0]
for (var i:Number = 0; i < 5; i++)
{
typeArr[i] = i;
// trace(typeArr[i]); // 0,1,2,3,4
}
// trace(typeArr); // 0,1,2,3,4
myType = 3;
bt.onPress = function()
{
var foo:String = "test";
// push method puts the element at the end of your array
// typeArr.push(foo);
// trace(typeArr); // 0,1,2,3,4,test
// splice method replace the 4e element (index 3) of your array
typeArr.splice(myType, 1, foo);
trace(typeArr); // 0,1,2,test,4
}

Reordering an array in flash as3

I have an array of objects, each of which is assigned an ID when it is first created. I give the user the ability to visually reorder the objects, which changes their position in the array. They then have the option to save that order using a flash sharedObject or "cookie" and then later, if they reopen the flash file, I want them to be able to hit a button to restore that order. I'm just not sure what the syntax would be to set the object's index within the array. Here's my code:
VARIABLES:
var project_settings = SharedObject.getLocal("settings"); //saves all project settings for the next time the file is opened
var project_order:Array = []; //saves project order for the next time the file is opened
var project_display:Array = []; //saves whether each project should be displayed or hidden for the next time the file is opened
SAVE CODE:
function saveOrder(){
for (var i=0;i<project_array.length;i++){
project_order[i] = project_array[i].id;
project_display[i] = project_array[i].projectThumb.thumbActive;
}
project_settings.data.order = project_order;
project_settings.data.active = project_display;
//trace (project_settings.data.active[1]);
project_settings.flush(); //saves most recent "cookie"
}
RESTORE CODE:
function loadOrder(){
for (var i=0;i<project_array.length;i++){
/* NEED THE CODE THAT GOES HERE. BASICALLY, PROJECT_ARRAY[i] SHOULD BE THE ITEM WITH AN ID EQUAL TO PROJECT_SETTINGS.DATA.ORDER[i] */
}
}
Something like this should work:
function loadOrder()
{
var dict = new Dictionary();
for (var i = 0; i < project_array.length; i++)
dict[project_array[i].id] = project_array[i];
project_array = [];
for (var i = 0; i < project_settings.data.order.length; i++)
project_array[i] = dict[project_settings.data.order[i]];
}
Just load in your array and sort on the ID. Something like this should work:
private function _loadArray():void
{
// fill in your array
project_array.sort( this._sortFunc );
}
// replace the * by whatever your object type is
private function _sortFunc( a:*, b:* ):int
{
return a.id - b.id;
}
More info: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sort()
Or even the sortOn() function (which might be easier) should work:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sortOn()

Resources