looping two arrays to get unique elements from one array - google-apps-script

I have
arr1 = [ 'Account2', 'Account4', 'Account4', 'Account5' ]
and arr2 = [ 'Account2', 'Account4', 'Account7' ]
I want to loop through both the arrays and get a new array with only the elements which are present in arr1 but not present in arr2
so the new array should have
arr3 = ['Account5']
I tried this
for (var i = 0; i < arr1.length; i++) {
for (var j = 0; j < arr2.length; j++) {
if (arr1[i] != arr2[j]) {
arr3.push(arr1[i]);
}
}
}
console.log("arr3", arr3);

Your code is not correct because it will push every element of arr1 that is not equal to any element of arr2, which will result in duplicates and unwanted values.
One possible way is to use a flag variable to check if an element of arr1 is present in arr2 or not, and only push it to arr3 if it is not present. For example:
var arr1 = [ 'Account2', 'Account4', 'Account4', 'Account5' ];
var arr2 = [ 'Account2', 'Account4', 'Account7' ];
var arr3 = [];
for (var i = 0; i < arr1.length; i++) {
var flag = false; // assume the element is not present in arr2
for (var j = 0; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
flag = true; // found the element in arr2, set the flag to true
break; // no need to continue the inner loop
}
}
if (!flag) { // if the flag is still false, it means the element is not present in arr2
arr3.push(arr1[i]); // push it to arr3
}
}
console.log("arr3", arr3); // ["Account5"]

Related

Retrieving google form response data

I have a google form, where I need to use item ID and get all the response for that Item.
I have the below script which will timeout if the form has more than 3000 responses, as its inefficient
How Do I optimize it to retrieve all the items in a short span of time
fO.items = ["ItemID1","ItemID2","ItemID3"...];
for (var i = 0; i < responses.length; i++) {
var response = responses[i];
var otherItems = '';
var flag = true;
for (var j = 0; j < fO.items.length; j++) {
var item = form.getItemById(parseInt(fO.items[j]));
if (response.getResponseForItem(item))
var otherItems = otherItems + "\t" + response.getResponseForItem(item).getResponse();
else
flag = false;
}
if (flag) {
columnData.push(otherItems);
responseIds.push(response.getId());
}
}
Currently, your code is getting the item object with the following line:
var item = form.getItemById(parseInt(fO.items[j]));
So, that line of code is reading the Form many times.
You could try getting the item objects once, putting them into a JSON object, and then retrieving them as needed.
I haven't tested this code, and I don't know if it will work, or if it will be faster if it does work. But thought I'd share the idea.
function getSomeAnswers() {
var form,flag,i,item,itemID,itemList,itemsObject,
k,L,L_items,otherItems,responses,response,thisAnswer;
itemList = ["ItemID1","ItemID2","ItemID3"];
form = FormApp.getActiveForm();
responses = FormApp.getActiveForm().getResponses();
itemsObject = {};
L_items = itemList.length;
for (i = 0; i < L; i++) {//Compile a list of item objects
itemID = parseInt(itemList[i]);
itemsObject[itemID] = form.getItemById(itemID);
}
L = responses.length;
for (i = 0; i < L; i++) {
response = responses[i];
otherItems = '';
flag = true;
for (k in itemsObject) {//Loop through every item to get
item = itemsObject[k];
thisAnswer = response.getResponseForItem(item);
Logger.log(thisAnswer)
if (thisAnswer)
otherItems = otherItems + "\t" + response.getResponseForItem(item).getResponse();
else
flag = false;
}
/*
if (flag) {
columnData.push(otherItems);
responseIds.push(response.getId());
}
*/
}
}

Checking for straight combination in poker

I want to check for a straight combination in a poker game.
So, I have this array: var tempArr:Array = new Array;
I have this for sorting the array:
for (i = 0; i < 7; i++)
{
tempArr[i] = pValue[i];
}
tempArr.sort( Array.NUMERIC );
pValue is the value of the cards, it's have range from 2 to 14.
So, if I have this Array: tempArray = [2,3,3,4,5,5,6];
How can I check if I have a straight combination in my hand?
Set a bucket array to save if you got a card in hand
var t:Array = [];
//t[2] = 1;mean you have 2
// t[3] = 0;mean you don't have 3
//first initialize t
for(var i:int = 0; i < 15; i++)
{
t[i] = 0;
}
//then set the values from tempArray
for (var j:int = 0; j < tempArray.length; j++)
{
t[tempArray[j]] = 1;
}
//if you have a straight combination in your hand
//you will get a k that t[k] & t[k-1]& t[k-2] & t[k-3] & t[k-4] == 1
var existed:boolean = false;//the flag save if you got a straight combination
for (var k:int = t.length - 1; k >= 4; k--)
{
if (t[k] == 0)
{
continue;
}
if ((t[k] & t[k-1] & t[k-2] & t[k-3] & t[k-4]) == 1)
{
existed = true;
break;
}
}

Issue with assigning Google Map Autocomplete results to variables

I have issue with with this line:
var user-city = addressObj[j].long_name;
I see proper value in console log but can't assign it to the variable.
function onPlaceChanged() {
var places = autocomplete.getPlace();
//console.log(places);
// var place = places[0];
console.log(places);
console.log(places.address_components);
user_home_address = places.name;
for(var i = 0; i < places.address_components.length; i += 1) {
var addressObj = places.address_components[i];
for(var j = 0; j < addressObj.types.length; j += 1) {
if (addressObj.types[j] === 'locality') {
// console.log(addressObj.types[j]); // confirm that this is 'city'
var user-city = addressObj[j].long_name;
// console.log(addressObj.long_name); // confirm that this is the city name
}
}
for(var j = 0; j < addressObj.types.length; j += 1) {
if (addressObj.types[j] === 'administrative_area_level_1') {
// console.log(addressObj.types[j]); // confirm that this is 'province'
// console.log(addressObj.short_name); // confirm that this is the province name
}
}
}

Cleaner way to get a key and value from JSON

Currently the way that I am taking a JSON string where I "Don't know the contents" and pulling the keys and the values is as follows:
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var arrLen = arr.length;
for(var i = 0; i < arrLen; i++){
var myKeys = Object.keys(arr[i]);
var keysLen = myKeys.length;
for(var x = 0; x < keysLen; x++){
keyName = myKeys[x];
keyValueStr = "arr[i]."+keyName;
keyValue = eval(keyValueStr);
console.log(keyName+':'+keyValue);
}
}
There has to be a cleaner and more efficient way of doing this. Any suggestion would be appreciated.
Using jQuery you can use http://api.jquery.com/jQuery.parseJSON/ & Object.keys - Than:
var obj = jQuery.parseJSON('{"manager_first_name":"jim","manager_last_name":"gaffigan"}');
var keys = Object.keys(obj);
jQuery.each(keys,function(k, v){
console.log(v);
console.log(obj[v]);
});
Create an object and initialize it with your JSON:
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var JSONObject = new MyJSONObject(arr);
in your constructor, set the object's properties.
You could use for-in loop which iterates over the enumerable properties of an object, in arbitrary order.
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
for (var i = 0; i < arr.length; i++) {
var currentObj = arr[i];
for (var item in currentObj) {
console.log(item + " : " + currentObj[item]);
}
}
If your array always have only one item, you could omit the outermost for loop and just use arr[0]
var currentObj = arr[0];
for (var item in currentObj) {
console.log(item + " : " + currentObj[item]);
}

setting the chances of occurrence of elements in an array

For example I have 3 elements in an array:
public function randomTile():Number
{
var tiles:Array = new Array(fire,ice,water);
var index:Number=Math.floor(Math.random()*tiles.length);
return tiles[index];
}
How to set the chances of occurrence of fire(70%), ice(10%), and water(20%)?
This should work for any number of elements and you can specify any chance value.
var tiles:Array = [
{"item":"fire", "chance":70 },
{"item":"ice", "chance":10 },
{"item":"water","chance":20}
];
var picked:Object = pickRandomByChance(tiles);
trace(picked.item);
public function pickRandomByChance(options:Array):Object
{
var copy:Array = [];
var range:Number = 0;
for (var i:int = 0; i < options.length; i++)
{
copy.push( { "item":options[i].item, "chance":options[i].chance } );
range += copy[i].chance;
if (i > 0)
copy[i].chance += copy[i - 1].chance;
}
var pick:Number = Math.floor(Math.random() * range);
for (i = 0; i < copy.length; i++)
{
if (pick <= copy[i].chance)
return copy[i];
}
return null;
}
There quite a few ways you could do this, and it largely depends of the scope of your project. If you just have the three elements, using a switch statement would be easy:
var rand:Number = Math.random();
switch(true){
case rand >= .3:
//use fire
break;
case rand >= .1
//use water
break;
default:
//use ice
}
Someone else may have a better way though