I am attempting to have a function compare objects in an array and see if they are the same
function alexareturn(alexaword, wordlist) {
var rhyme = false
console.log(alexaword + wordlist);
for (var i = 0; i <= alexaword.length; i++) {
for (var j = 0; j <= wordlist.length; j++) {
if (alexaword[i].indexOf(wordlist[j]) > -1) {
rhyme = true;
break;
}
}
}
if (rhyme) {
return true;
} else {
return false;
}
}
My console is returning two proper arrays, however I am getting the error Cannot read indexOf (undefined). If i am getting console to return a proper array right before, how can one of them be undefined?
I would just like to call my function, and have it return true if there is a match of the two arrays, Thanks for your help!
Your outer for loop runs from 0 - alexaword.length (inclusive). In the last iteration alexaword[i] would be undefined.
for (var i = 0; i < alexaword.length; i++) would fix it.
Related
I need to create function that creates and returns array. Its size needs to match the rows parameter, and each next element contains consecutive integers starting at 1. To call this function I need to use argument 5. Here below is what I wrote so far. Can you tell me what's wrong here?
function createArray(rows) {
for(let i = 1; i < rows.length; i++) {
console.log(rows[i]);
}return rows;
}
createArray(5);
You need to create an array and return it, whereas you return just rows which is a number. The idea of using a for loop is the best way to go. In that loop you just need to set the values in the array accordinlgy.
Another problem in your code is that rows is of type number and does have a property length but that does not have the desired value. So we just use rows in the for loop. We start the loop with i = 0 because array indices start at 0.
Code
function createArray(rows) {
let arr = new Array(rows);
for (let i = 0; i < rows; i++) {
arr[i] = i + 1;
}
return arr;
}
console.log(createArray(5));
We can not use length property for number. create an empty array and then push values into that array until required size is achieved.
function createArray(rows) {
var arr = [];
for(let i = 1; i <= rows; i++) {
arr.push(i);
}return arr;
}
createArray(5);
I think what you want is createArray(5) return [1,2,3,4,5] if that's the case you could do this
function createArray(rows) {
const arr = []
for(let i = 1; i <= rows; i++) {
arr.push(i);
}
return arr;
}
console.log(createArray(5));
The problem is, that rows.length is not available on 5, because 5 is a number.
You have to use an array as parameter:
Array(5) creates an array with the length of 5 and fill("hello") fills this array with "hello" values.
function createArray(rows) {
for (let i = 1; i < rows.length; i++) {
console.log(rows[i]);
}
return rows;
}
const rows = Array(5).fill("hello");
createArray(rows);
I don't know, if this is the behaviour you want, if not, I misunderstood your question.
The code below is not giving me the expected result.
It's to compare rows from two ranges and, although the second range's last row equals the one from the first range, it gives me false as the result.
var entryValuesCom = sheet.getRange(7, 1, LastRowSource, 9).getValues();
var dbDataCom = dbSheet.getRange(2, 1, dbSheet.getLastRow(), 9).getValues();
var entryVlArray = new Array();
var dbArray = new Array();
for (var r = 0; r < entryValuesCom.length; r++) {
if (entryValuesCom[r][0] != '' && entryValuesCom[r][5] != 'Daily Ledger Bal') {
entryVlArray.push(entryValuesCom[r]);
}
}
for (var a = 0; a < dbDataCom.length; a++) {
if (dbDataCom[a][1] != '' && dbDataCom[a][8] == bank) {
dbArray.push(dbDataCom[a]);
}
}
var duplicate = false;
loop1:
for (var x = 0; x < entryVlArray.length; x++) {
loop2:
for (var j = 0; j < dbArray.length; j++) {
if (JSON.stringify(entryVlArray) == JSON.stringify(dbArray)) {
duplicate = true;
break loop1;
}
}
}
Here's a snapshot of how the array is coming:
I've tried it using .join(), but still...
This is for thousands of rows, so is this going to do well performance wise?
I believe your goal as follows.
You want to compare the arrays of entryVlArray and dbArray using Google Apps Script.
When the duplicated rows are existing between entryVlArray and dbArray, you want to output duplicate = true.
Modification points:
When your script is modified, at if (JSON.stringify(entryVlArray) == JSON.stringify(dbArray)) {, all 2 dimensional arrays are compared. I think that this might be the reason of your issue. From your script, I think that it is required to compare each element in the 2 dimensional array.
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
var duplicate = false;
loop1:
for (var x = 0; x < entryVlArray.length; x++) {
loop2:
for (var j = 0; j < dbArray.length; j++) {
if (JSON.stringify(entryVlArray) == JSON.stringify(dbArray)) {
duplicate = true;
break loop1;
}
}
}
To:
var duplicate = false;
for (var x = 0; x < entryVlArray.length; x++) {
for (var j = 0; j < dbArray.length; j++) {
if (JSON.stringify(entryVlArray[x]) == JSON.stringify(dbArray[j])) {
duplicate = true;
break;
}
}
}
console.log(duplicate)
By this modification, when each element (1 dimensional array) in the 2 dimensional array is the same, duplicate becomes true.
Note:
As other method, when an object for searching each row value is prepared, I think that the process cost might be able to be reduced a little. In this case, the script is as follows. Please modify as follows.
From:
var duplicate = false;
loop1:
for (var x = 0; x < entryVlArray.length; x++) {
loop2:
for (var j = 0; j < dbArray.length; j++) {
if (JSON.stringify(entryVlArray) == JSON.stringify(dbArray)) {
duplicate = true;
break loop1;
}
}
}
To:
var obj = entryVlArray.reduce((o, e) => Object.assign(o, {[JSON.stringify(e)]: true}), {});
var duplicate = dbArray.some(e => obj[JSON.stringify(e)]);
References:
reduce()
some()
Added:
About your following 2nd question,
AMAZING!!!! Would there be a way of capturing these duplicates in a pop up, using reduce() and some()?
When you want to retrieve the duplicated rows, how about the following script? In this case, I thought that filter() is useful instead of some().
Modified script:
var obj = entryVlArray.reduce((o, e) => Object.assign(o, {[JSON.stringify(e)]: true}), {});
// var duplicate = dbArray.some(e => obj[JSON.stringify(e)]);
var duplicatedRows = dbArray.filter(e => obj[JSON.stringify(e)]);
console.log(duplicatedRows)
In this modified script, you can see the duplicated rows at the log.
About a pop up you expected, if you want to open a dialog including the duplicated rows, how about adding the following script after the line of var duplicatedRows = dbArray.filter(e => obj[JSON.stringify(e)]);?
Browser.msgBox(JSON.stringify(duplicatedRows));
I am trying to compare the word hello and hey both of which are in an array if they are equal and my code is returning true and yet they are not. how can i modify my code to make it return false when comparing the two words.
function mutation(arr) {
var sorted =[];
for (var i =0; i<arr.length; i++) {
sorted.push(arr[i].toLowerCase());
}
for (var j =0; j<sorted.length;j++) {
for(var k=0; k<sorted.length; k++) {
if(sorted[j] == sorted[k]) {
return true;
} else{
return false;
}
}
}
}
mutation(["hello", "hey"]);
Just change the second loop to start from j+1, because you are actually comparing 0 with 0 positions.
for(var k=j+1; k<sorted.length; k++) {
The code sample given the argument provided to 'mutation' has 2 items. My solution also presumes that arr is an Array containing 2 items.
function mutation(arr) {
if(arr[0] !== arr[1]) {
return false;
}
return true;
}
mutation(["hello", "hey"]);
Hi I have an array that looks like:
hrarray = [-9,-7,0,3,7,8]
I've been trying to work out a function that selects the first non-negative (inc. 0) number in the array and returns the index (var elemid):
for (var i = 0, len=hrArray.length; i<len; i++) {
var num = hrArray[i];
if(num > 0) {
var elemid = i; //returns first non-negative element index
}
else if(num < 0) {}
Is my code logic correct?
I don't see you returning anything.
You can get the first non-negative with a single line:
for (var i = 0, len = arr.length; i < len && arr[i] < 0; i++);
Basically, we place the check for negatives in the for-loop guard. It will break once it finds a non-negative and hence return i of that first non-negative.
Update #1 (to use in a function):
function getFirstNonNegative(arr) {
for (var i = 0, len = arr.length; i < len && arr[i] < 0; i++);
// Use a ternary operator
return (i === len) ? -1 : i; // If i === len then the entire array is negative
}
Your code will assign to elemid the last non-negative in the array. Try this:
var elemid=-1; // elemid should be declared outside the for statement
for (var i = 0, len=hrArray.length; i<len; i++) {
if(hrArray[i] > 0) {
elemid = i; //returns first non-negative element index
break;
}
}
The main problem I see is that you're not breaking out of the loop once you find a non-negative value. This can be done with a break statement, or if you want to exit a function immediately, a return statement.
The function should look a bit like this:
function findNonNegative(arry) {
for (var i = 0, len = arry.length; i < len; i++) {
if(arry[i] >= 0)
return i;
}
return -1;
}
Note that this method returns -1 if no non-negative elements are found.
And with a little tweaking, this can be shortened to:
function findNonNegative(arry) {
for (var i = 0; arry[i] < 0; i++);
return i < arry.length ? i : -1;
}
This version takes advantage of the behavior of the for loop to both test our values inside the loop and break out once a desired value is found. It also depends on the fact that x < y always returns false if x is undefined, thus ensuring we do not end up with an infinite loop. The last conditional expression is there to make the return value equal -1 if no non-negative elements were found; that can be reduced to just return i; if you are okay with the return value being arry.length in that case.
function ArrayAdditionI(arr) {
var numbers = arr();
var arraySum = "";
for (var i = 0; i < numbers.length; i++) {
arraySum = arraySum + arr[i];
};
if (numbers.max() <= arraySum) {
arr = true
}
else if (numbers.max() > arraySum) {
arr = false;
}
return arr;
}
I need to find the numbers stored in an array called arr and check if they add up to or total the greatest number or whether they do not. If so, return true. If not, return false.
I am not sure I am calling the array correctly in the beginning.
Thanks
I actually wrote a library I use just for functions like this.
http://code.google.com/p/pseudosavant/downloads/detail?name=psMathStats.min.js
You would just do this:
var arr = [1,2,3,4,5,300];
if (arr.max() > arr.sum()){
// Max is greater than sum...
}
One warning though. This library prototypes the Array object which could mess up other scripting that uses for (var i in arr) on an Array, which you shouldn't ever do. I am actually almost done with v2 of the library with a number of new functions and it no longer prototypes the Array object.
You can just grab the .max() and .sum() methods from the code, and use them without the prototyping if you want though.
maxArray = function (arr) {
return Math.max.apply(Math, arr);
}
sumArray = function (arr) {
for (var i = 0, length = arr.length, sum = 0; i < length; sum += arr[i++]);
return sum;
}
You mean something like this?
function ArrayAdditionI(arr) {
for (var i = 0, sum=0; i < arr.length; i++) {
sum += arr[i];
}
return Math.max.apply( Math, arr ) <= sum;
}
function ArrayAdditionI(input) {
var arraySum, max;
arraySum = max = input[0];
for (var i = 1; i < input.length; i++) {
arraySum += input[i];
if(input[i] > max){
max = input[i];
}
};
return arraySum >= max;
}
If the numbers are positive, the answer is guaranteed - the sum is always greater than or equal to the max. If you need to calculate it, ddlshack's code looks good.
Looking at your code, there are a number of issues. First of all, arr() should error out. Arrays aren't functions, and trying to treat them as a function does nothing. Your array is already usable when it is passed in. Additionally, you want to initialize arraySum to 0, not "". The way you are doing it, the values in the array will be coerced into strings and concatenated together, which is not what you are looking for. Finally, arrays don't implement a max() method, but Math does, and functions/methods in javascript can be applied to an array in the manner shown by ddlshack and others.
There are some syntax errors: type missmatch, wrong assign and calls to method that doesn't exists. If I'm understanding what do you want to do, this is the correct code(if changing items order is not a problem):
function ArrayAdditionI(arr) {
var ret = false;
var arraySum = 0;
for (var i = 0; i < arr.length; i++) {
arraySum += arr[i];
}
if (arr.sort()[arr.length-1] <= arraySum) {
ret = true
}
return ret;
}