Checking for existing array in array before pushing - javascript

I missing something when trying to push to an array while preventing duplicates.
I keep figuring out code that will push every occurence of an employee to the new employees array but I cannot figure out how to only push an unique list.
My final array is a 2d array so that can be setValues() back into a column in the Google sheet.
function queryEmployees(){
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lRow = sh.getLastRow();
var data = sh.getRange(1,1,lRow,2).getValues();
var employees = [];
for(i=0;i<data.length;i++){
if(data[i][0]==='Team member evaluated'){
if(employees.indexOf([data[i][1]])===-1){
employees.push([data[i][1]]);
}
}
}
Logger.log(employees);
Logger.log(employees.length);
SpreadsheetApp.getActiveSpreadsheet().getSheets()[1]
.getRange(1,1,employees.length,1).setValues(employees);
}

IndexOf does not work with objects in arrays without your rewriting the function or writing your own. It works fine with strings, though. So a simple fix is to create a parallel array of strings, which allows us to keep your code almost intact. Thus, add,
var employeesIndex=[];
after your
var employees=[]
change the condition on your inner "if" clause to
(employeesIndex.indexOf(data[i][1])===-1)
and within that if block add a line to update the index
employeesIndex.push(data[i][1]);
That way the index tracks duplicates for you while your employees array contains arrays like you need.

Related

JS: Iterate over an array of objects to update object

I am trying to iterate over an array of array objects to de-dupe and sort the data within each. The function onlyUnique returns unique values in an array. The problem is, it doesn't work as intended.
arr_lists = [arr_1, arr_2, arr_3, arr_4, arr_5, ...]
for (var list_obj of arr_lists) {
list_obj = list_obj.join().split(',').filter(onlyUnique);
list_obj.sort();
Logger.log(list_obj);
}
The logger results show true (i.e. they are what I am looking for), but the original array is unchanged, although I think it should have been updated.
I've tried assigning the filtered array to a new array... nope.
I know that I could add a thousand lines of code to achieve the results, but that seems silly.
I suspect it's something obvious.
You can simply achieve it by using Set data structure to remove the duplicates and Array.sort() compare function to sort the elements in an array.
Live Demo :
const arr_lists = [[2,3,5,6], [7,2,5,3,3], [1,5,3], [4,7,4,7,3], [1,2,3]];
arr_lists.forEach((arr, index) => {
arr_lists[index] = [...new Set(arr)].sort((a, b) => a -b);
})
console.log(arr_lists);

Google Apps Script Better Way to Get Unique Values

I have working code that takes data from two non-adjacent columns in a Google Spreadsheet, looks for unique values in the first column, and if unique creates a new array with the unique value from the first column and corresponding value in the second column. The problem is, the data I am using is already somewhat long (413 rows) and will only get longer over time. It takes about 1-2 minutes for the code to run through it. I've been looking for a shorter way to do this and I've come across the filter() and map() array functions which are supposedly faster than a for loop but I can't get them implemented correctly. Any help with these or a faster method would be greatly appreciated. The code I have right now is below.
function getkhanassignments(rows) {
var assignmentsraw = [];
var temparray = [];
var previousassignment = datasheet.getRange(50,1).getValue();
for(i=0, j=0;i<rows-1;i++) {
if(datasheet.getRange(50+i,1).getValue() != previousassignment) {
previousassignment = datasheet.getRange(50+i,1).getValue();
assignmentsraw[j] = new Array(2);
assignmentsraw[j][0] = datasheet.getRange(50+i,1).getValue();
assignmentsraw[j][1] = datasheet.getRange(50+i,8).getValue();
j++;
}
}
Logger.log(assignmentsraw);
return assignmentsraw;
}
The answers I've found elsewhere involve just getting unique values from a 1d array whereas I need unique values from a 1d combine with corresponding values from another 1d array. The output should be a 2d array with unique values from the first column and their corresponding values in the second column.
Solution:
The best practice of looping through ranges in Google Apps Script is to dump the range values into a 2D array, loop through that array, and then return the output array back to Google Sheets.
This way, there would be no calls to Sheets API inside loops.
Sample Code:
function getkhanassignments(rows) {
var assignmentsraw = [];
var table1 = datasheet.getRange(50,1,rows).getValues();
var table2 = datasheet.getRange(50,8,rows).getValues();
var previousassignment = table1[0][0];
assignmentsraw.push([table1[0][0],table2[0][0]]);
for(i=0; i<rows; i++) {
if (table1[i][0] != previousassignment) {
assignmentsraw.push([table1[i][0],table2[i][0]]);
previousassignment = table1[i][0];
}
}
Logger.log(assignmentsraw);
return assignmentsraw;
}
References:
Class Range
push()

Transpose a two dimensional Array with one row and many columns into a two dimensional array with many rows and one column

I have a two dimensional array with one row and many columns. I would like to flip this into a two dimensional array variable with one column and many rows.
var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(market);
var shrinkLog = SpreadsheetApp.openById("1h3B4HN4mEnBvlx-8aNa9_2ooEZrkY_qLuJcuJXZq7dM").getSheetByName(market);
var dataArr = shrinkLog.getRange(2,3,1,shrinkLog.getLastColumn()).getValues();
I think the answer is in the map function, but keep returning errors, or getting different versions of the same one dimensional array. help is much appreciated.
I guess your goal as follows.
From var dataArr = shrinkLog.getRange(2,3,1,shrinkLog.getLastColumn()).getValues(), you want to retrieve the result from [[data1, data2, data3,,,]] to [[data1], [data2], [data3],,,]].
In your case, shrinkLog.getRange(2,3,1,shrinkLog.getLastColumn()).getValues() returns [[data1, data2, data3,,,]]. So when your goal is achieved with map, the modified script is as follows.
Sample script:
var dataArr = shrinkLog.getRange(2,3,1,shrinkLog.getLastColumn()).getValues()[0].map(c => [c]);
Note:
In this case, please enable V8 runtime.
Reference:
map()

How to move an object to the top of an array with AngularFire?

I am trying to move an object to the top of an array with AngularFire.
My array in Firebase is simmilar to this:
$scope.todos = [
{title:"Work out", timetag:"new Date()", done: false },
{title:"Home work", timetag:"new Date()", done: false }
];
I created a function that uses vanilla javascript that stores the object to a variable. The function deletes the object from the array that you want to move up to the beginning of the array. The function then replaces the object you stored to a variable to the beginning of the array.
Here is the code I have:
$scope.moveUpPriority = function($index){
var toMove = $scope.todos[$index];
delete $scope.todos[$index];
$scope.todos.splice(0,0, toMove);
$scope.todos.$save();
};
This code snippet is almost completely working the way I want. When I run this on my todo list, It moves the todo task up the array. However when I refresh the page, it doesn't stick.
What are the appropriate AngularFire Methods to completely save or set this type of javascript code to my Firebase Backend?
To preserve the order of the TODOs you could add a property named for example priority.
When a TODO is dragged/moved up the priority list you should then re-set the priority values of the TODOs save them and order them by that property in your template.
Okay so array methods like splice(), push(), pop(), shift(), unshift(), and reverse() will cause the Firebase Array to break.
So my work around was to edit/change the array with standard Javascript Array methods.
Then I store a copy of the local(edited)state array to a variable.
Then I delete the Firebase array.
Then I pushed the keys of the local array to Firebase.
Here is the code below:
$scope.moveUpPriority = function($index){
var toMove = $scope.todos[$index]; //save copy of $index todo
$scope.todos.splice($index,1); //removes item at $index
$scope.todos.splice(0,0, toMove); //adds item toMove to the start of array
var backup = $scope.todos; //copy back up array
for(var b = 0; b<= $scope.todos.length; b++){
$scope.todos.$remove($scope.todos[b]); //remove items from array
}
for(var i = 0; i<= backup.length; i++){
$scope.todos.$add(backup[i]); // add items from back up array
}
};

Storing values in array and retrieving from array when checkbox is checked

I am storing some values in array like this.
var test = [];
I am pushing the values to this array as test.push(sample);
I have some logic for calculating this value
var sample= (a/b.length)*100;
When I click on a button, the above logic for calculating value of sample is done and once I got the value of sample I am pushing it to test[] array. Now I want to retrieve all the values from the test[] array whenever I check the checkbox. I am able to do all this but I am facing a problem here. only the last pushed value is saving. but I want to save all the values that are being pushed. can anyone please help me in solving this issue.
Quick response is needed and appreciated
Regards
Hema
You need to use 2 dimensional array for this.
Use
var test= new Array();
then assign value test['someKey']=sample;
or test.push(sample); . you can retrieve array value like alert(test[0]) or by iterating array with $.each(test,function(index,value){alert(value)});
What you want to do is create an Array which would function as a list of value sets.
You would then be able to push all the changes into an array, and put it in the list.
for instance:
var mainList = new Array();
var changeListA = new Array();
var changeListB = new Array();
// do some stuff on change list **a** .. push(something)
changeListA .push(something);
changeListA .push(something);
changeListA .push(something);
// do some stuff on change list **b** .. push(something)
changeListB .push(changeListB);
mainList.push(changeListA);
Your question is not perfectly clear to me, however I can at least provide a small jsFiddle that proves to you that (how) array.push works.
Other answers indicate that what you want is either a two dimensional array, or a "hashmap" or "associative array" where the array values are stored using a key name. The code here can be used in the fiddle to achieve either or...
http://jsfiddle.net/xN3uL/1/
// First if you need 2 dimensional arrays:
myArray.push( ["Orange", "Apple"] );
myArray.push( ["Mango", "Pineapple"] );
// Secondly, if you need hashmap or associative array:
var myObj = {};
myObj['key'] = 'value';
alert(myObject.key);

Categories