Actionscript: select and display the duplicated value from an array - actionscript

Please how can I get the duplicated value from an array ?
Ex:
Array [10,3,10,10]
display that we have 3 duplicated in location 1,3 and 4
Regards
I have tried this one :
q = new Array();
q = [A, B, C, D];
qValue = function (array) {
equal = array[0];
for (j=0; j<array.length; j++) {
if (array[j]===equal) {
equal = array[j];
}
}
return equal;
};
trace(qValue(q));

Something like this should work:
var array:Array = [1,2,3,4,3];
// create a dictionary and go through our array pulling out the keys
var dict:Dictionary = new Dictionary();
for each( var i:int in array )
{
if( i in dict ) // checks if the number is already in our dict as a key
dict[i]++;
else
dict[i] = 1;
}
// now go through our dictionary, finding the duplications
for( var key:* in dict )
{
var num:int = dict[key];
if( num == 1 )
continue; // single value - ignore
trace( "We have " + num + " occurrences of " + key );
}
Edit
To also have the locations (indicies) of the repeated values, use this instead:
var array:Array = [1,2,3,4,3];
// create a dictionary and go through our array, pulling out the values
var dict:Dictionary = new Dictionary();
var len:int = array.length;
for( var i:int = 0; i < len; i++ )
{
var val:int = array[i]; // get the value from the array
if( !( val in dict ) ) // if it's not in our dictionary, create a new array
dict[val] = [];
dict[val].push( i ); // add the index of the value to the array
}
// now go through our dictionary, finding the duplications
for( var key:* in dict )
{
var indicies:Array = dict[key];
if( indicies.length <= 1 )
continue; // single value - ignore
trace( "The value " + key + " is repeated " + indicies.length + " times. Indicies: " + indicies );
}
Edit - AS2 no "if in"
Add the function:
function _getArray( obj:Object, val:Number ):Array
{
// try and find the one already created
for( var key:* in obj )
{
if( key == val )
return obj[val];
}
// make a new one
var a:Array = [];
obj[val] = a;
return a;
}
Your array loop should now read
for( var i:int = 0; i < len; i++ )
{
var val:int = array[i]; // get the value from the array
var occurrenceArray = _getArray( obj, val ); // obj = dict
occurrenceArray.push( i ); // add the index of the value to the array
}

Related

error when retrieve values from google script spreadsheet

I have this script in google script spreadsheet:
function doGet() {
var response = [];
var ss = SpreadsheetApp.getActive();
var thisSheet = ss.getSheetByName('product');
var lastRow = thisSheet.getLastRow();
var allValues = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
var objectResponse = {};
for(var i = 2; i < lastRow ; ++i){
objectResponse.title = allValues[i][1];
objectResponse.url = allValues[i][8];
response.push(objectResponse);
};
return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}
I make this loop to create an array of objects like this
[
{ title: 'first_title_on2column' , URL: 'first_url_on9column'},
{ title: 'second_title_on2column' , URL: 'second_url_on9column'},
...
//until ends <lastRow>
]
but the results is the same on each object. Same 'title' and 'URL'.
How to retrieve each 'title' and 'URL' values?
your code does not add new object elements to the response array, but only new references to the same object - so all your values are the same
var objectResponse = {};
for(var i = 2; i < lastRow ; ++i){
objectResponse.title = allValues[i][1];
objectResponse.url = allValues[i][8];
response.push(objectResponse);
};
try replacing your code block with a new one and see what happens
for(var i = 2; i < lastRow ; ++i){
response.push({title: allValues[i][1], url:allValues[i][8]});
};
or even like this
allValues.forEach(dataRow => response.push({title: dataRow[1], dataRow[8]}))

Set colors at once on a range of cells

Setting colors of cells 1 by 1 is extremely slow. It is advised to do that by assigning an array to the range. I read about that and there is often refered to the following sample. However I can't get this to work so it doesn't help me.
var cell = sheet.getRange('a1');
var colors = new Array(100);
for (var y = 0; y < 100; y++) {
xcoord = xmin;
colors[y] = new Array(100);
for (var x = 0; x < 100; x++) {
colors[y][x] = getColorFromCoordinates(xcoord, ycoord);
xcoord += xincrement;
}
ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors);
My piece of code is the following and ends with the message (error): Cannot convert array to object[[]], pointing at the last line.
function TabelMarkeren() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef") // 6 by 3;
var colors = [];
for (var row = 1; row <= selection.getNumRows(); ++row) {
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 1] = "#86d8b6";
}// if
else {
colors[row, 1] = "c4c4a4";
}// else
colors[row, 2] = "blue";
colors[row, 3] = "green";
}// for
SpreadsheetApp.getActiveSpreadsheet().
getRangeByName("Proef").setBackgrounds(colors);
}
When I use a Browser.msgBox . . to show me some values from the array. It is ok. But clearly setBackgroundColors wants an object and not an array.
The setBackgrounds expect the value in [][] and you are passing the values in []. Refer the below code.
function TabelMarkeren() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef") // 6 by 3;
var finalColors = [];
for (var row = 1; row <= selection.getNumRows(); ++row) {
var colors = [];
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 1] = "#86d8b6";
} // if
else {
colors[row, 1] = "c4c4a4";
} // else
colors[row, 2] = "blue";
colors[row, 3] = "green";
finalColors.push(colors)
} // for
Logger.log(colors)
SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef").setBackgrounds(finalColors);
}
Thank you Ritz, I have it working now.
I also had to change the colomn indexes from 1,2,3 to 0,1,2. That was another mistake. The code is now:
function TabelMarkerenn() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef");
var finalColors = []
for (var row = 1; row <= selection.getNumRows(); ++row) {
var colors = [];
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 0] = "#86d8b6";
}// if
else {
colors[row, 0] = "#c4c4a4";
}// else
colors[row, 1] = "blue";
colors[row, 2] = "green";
finalColors.push(colors);
}// for
Logger.log(finalColors);
SpreadsheetApp.getActiveSpreadsheet().
getRangeByName("Proef").setBackgrounds(finalColors);
}
Very happy with this, but . . . isn't there a way to directly use the finalColors array? Or is that slower or just not common practice.

How to convert a OPENLAYERS 3 postcompose method to a normal one?

I am trying to animate a line based on the given coordinates array comprising of latitude and longitude and I want to call my function just once and my coordinates name is: replayData.
map.on('postcompose', function (event) {
var vectorContext = event.vectorContext;
var frameState = event.frameState;
vectorContext.setFillStrokeStyle(null, animatedLineStroke);
var features = lineVectorSource.getFeatures();
for (var k = 0; k < features.length; k++) {
var feature = features[k];
if (!feature.get('finished')) {
var coords = feature.getGeometry().getCoordinates();
var elapsedTime = frameState.time - feature.get('start');
var elapsedPoints = elapsedTime * pointsPerMs;
if (elapsedPoints >= coords.length) {
feature.set('finished', true);
}
var maxIndex = Math.min(elapsedPoints, coords.length);
var currentLine = new ol.geom.LineString(coords.slice(0, maxIndex));
if (feature.get('iValue') == undefined || feature.get('iValue') < k) {
// drawMovingCarMarker(coords, k);
feature.set('iValue', k)
}
vectorContext.drawLineStringGeometry(currentLine, feature);
}
}
frameState.animate = true;
});
What this function is doing is first collecting all the values from for loop and then starting the animation. And because of this if I've 5 points the line between first two points will be drawn 5 times then 4,3, and so on.
Any help would be entertained. Thanks in advance.

Google Spreadsheet ||Typeerror : cannot read property '0'

I have a spreadsheet for project data with time-sheet for each month logged against each project ID
I want to iterate through each sheet and if there is matching project ID , I want to sum up the number of hours logged for each project.
I have written the following code but keep getting the
TypeError: Cannot read property "0" from undefined. (line 31).
This is my sheet : https://goo.gl/rrsSxI
And this is my Code.
function TotalHours(TaskID) {
var a = SpreadsheetApp.getActiveSpreadsheet().getSheets().length;
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var sum = 0;
// var fcol = 0;
for (var i = 1; i <= a; ++i) {
// var sheetname = sheets[i].getName();
//var cell = sheets[i].getActiveCell();
//Set active cell to A1 on each sheet to start looking from there
SpreadsheetApp.setActiveSheet(sheets[i])
//var sheet = sh.getActiveSheet();
var range = sheets[i].getRange("A1");
//* sheets[i].setActiveRange(range);
var data = sheets[i].getDataRange().getValues();
for (var row = 2; row <= data.length; ++row) {
if (data[row][0] == TaskID) {
for (var col = 2; col <= 31; ++col) {
sum += sheets[i].getRange(row, col).getValue();
}
}
}
}
return sum;
}
Can someone help me with what I am doing wrong.
I assume you want to exclude the sheet where the formula is going to be used ("Tracker" ?
See if this works ?
function TotalHours(TaskID) {
var sum = 0,
s = SpreadsheetApp.getActive(),
active = s.getActiveSheet().getName(),
sheets = s.getSheets();
for (var i = 0, slen = sheets.length; i < slen; i++) {
if(sheets[i].getName() != active) {
var sheetVal = sheets[i].getDataRange()
.getValues();
for (var j = 0, vlen = sheetVal.length; j < vlen; j++) {
if (sheetVal[j][0] == TaskID) {
for (var k = 2, rlen = sheetVal[j].length; k < rlen; k++) {
var c = sheetVal[j][k]
sum += c && !isNaN(parseFloat(c)) && isFinite(c)? c : 0; //check if cell holds a number
}
}
}
}
}
return sum;
}

How to Count and return the Values

I am facing a problem in the following script. I am not much into scripting at all and this is not my script also but here am getting the result which is grouping the values( For Example if i have a value A in three cells it should return the value as 3 instead it is returning AAA. Can someone help me out to count the values and return it
Thanks in Advance,
Here is the script :
function sumBackgroundColors(rangeString, color) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var sumRange = s.getRange(rangeString);
//var sum = 0;
var openCount = 0;
var sumRangeBackground = sumRange.getBackgroundColors();
var sumRangeValues = sumRange.getValues();
for(var row = 0; row < sumRangeBackground.length; row++ ) {
for(var col = 0; col < sumRangeBackground[0].length; col++ ) {
if( sumRangeValues[row][col]=="LG M"&& sumRangeBackground[row][col] == color ) {
openCount = openCount + sumRangeValues[row][col];
//if(sumRangeBackground[row][col] == color && sumRangeValues[row][col] == 1 ) {
// sum = sum + parseFloat(sumRangeValues[row][col]);
}
}
}
return openCount;
//return sum;
}
Here is a function which will take the value to be searched as argument. Rest of the things have been explained in comment lines.
function searchCount(value){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Get the whole data from activesheet in a 2D array
var data = sheet.getDataRange().getValues();
//Initialize counter
var count = 0;
//Iterate through the array
for(var i in data){
for(var j in data[i]){
// if a match found, increament the counter
if(value.toString == data[i][j]){
count++;
}
}
}
// return the count value
return count;
}
your problem could be due to openCount = openCount + sumRangeValues[row][col];
According to your example sumRangeValues[row][col] isn't an int. int + not an int = ??? if you want to keep a count of things you probably want openCount++ to replace that line instead, which is just a shortcut to openCount = openCount + 1;
Even if sumRangeValues[row][col] was an int, that line still wouldn't be what you're looking for. If you're searching for all the 3s in your spreadsheet your code would find your first 3, and then that line would execute 0 = 0 + 3 congrats, you just found 3 threes. You would continue to add three every time you found a three.
Waqar's code is essentially your code (amazingly simplified, but it iterates the same way) except he doesn't check color and he uses ++ instead of that line.

Resources