Comparing values in an array (app script) - javascript

first I'm new to Apps Script respectively Javascript. However in Google Sheets with Apps Script I have filled an array with the contents of one column. Now I would like to find matching values in this array. I tried the following code with a simple array like [2,5,3,6,2,7] and the code works. It doesn't work though with the values from the column (e. g. something like '110rt' or '38tzu0'):
let z = sheet.getRange("D2:D" + sheet.getLastRow())
let a = z.getValues()
for (let i = 0; i < a.length; i++) {
for (let k = i + 1; k < a.length; k++) {
if (a[i] == a[k]) {
console.log("hit")
}
}
}
So in the above code the if clause never becomes true and I don't understand why.

When you use getRange with multiple rows, it returns each row in a seperate sub-array.
The end result is a 2D array, where each sub-array represent a row.
For example:
[
[A1,B1,C1,...],
[A2,B2,C2,...],
[A3,B3,C3,...]
]
In your case, where you have only one column, it looks like that:
[[2 ],[5 ],[3 ],[6 ],[2 ],[7]]
[[D2],[D3],[D4],[D5],[D6],[D7]] // the matching cells
The buttom line is that you need to iterate a[k][0] and a[i][0]
let z = sheet.getRange("D2:D" + sheet.getLastRow())
let a = z.getValues()
for (let i = 0; i < a.length; i++) {
for (let k = i + 1; k < a.length; k++) {
if (a[i][0] == a[k][0]) {
console.log("hit")
}
}

Related

Getting an array index from 2 values

I wasn't sure how to properly word the title.
I have 2 indexes from a 2D array (x and y) and need to multiply them together to get the index for a second array (1D), however it's not that simple 'cause if x or y equals zero, it'll return zero regardless of the other value.
I could get around this using nested loops shown below:
int count = 0;
for( int i = 0; i < x; i++ )
{
for( int j = 0; j < y; j++ )
{
count++;
}
}
//count now equals desired value
...but that seems awfully impractical.
To me this seems like something that should be incredibly simple and I've put off asking until now, thinking that might be the case.
Let’s use the following data to create an example:
var array_2d = [[0,1,2],[3,4,5]];
var array_1d = [0, 1, 2, 3, 4, 5];
If all of your sub arrays have the same size, you can simply multiply your i index by your sub array’s length, in order to find the corresponding “row” of your 1 dimensional array. Then you can simply add the “column” index of your array.
But this would only work if you are working with width-fixed matrixes.
var sub_dimensional_array_length = 3;
for (var i = 0; i < array_2d.length; i++) {
for (var j = 0; j < array_2d[i].length; j++) {
var array_1d_index = (sub_dimensional_array_length * i) + j;
console.log(array_2d[i][j], array_1d[array_1d_index]);
}
}

Merge two arrays by value

I have a specific cuestion about merge arrays:
I'm using google charts and I need to do something like this
Combo Chart
To do something like that I need to fill this matrix
I did fine with axis x and axis y:
$scope.data= [];
$scope.data[0]= ['Months'];
angular.forEach($scope.consultors, function(consultor) {
$scope.data[0].push(consultor.no_user);
})
angular.forEach(months, function(month) {
$scope.data.push([month])
})
but, my problem is when i try to put $scope.relatorias, inside of $scope.data.
This is $scope.relatorias, this variable has the data of every consultor group by month, like this:
If you open each array look like this
I just need push ganancias_netas, but my problem is when there is an empty month, for example anapaula has data in every month but renato hasn't.
I have try to user for or for each but is doesn't work, I'm not an expert in matrix and this is my first time working on it.
fiddle: http://fiddle.jshell.net/rfcabal/5ftw7c8d/
/// UPDATE ///
I added this code that first fill with 0 $scope.data and then search for the values in relatorios and shoudl fill $scope.data, but for some reason jus fill with the last found value.
for (var i = 1; i < $scope.data.length; i++) {
for (var a = 1; a < $scope.data[0].length; a++) {
$scope.data[i][a] = 0;
for (var b = 0; b < $scope.relatorios[a-1].length; b++) {
console.log(a-1+' '+b+' '+3);
console.log($scope.relatorios[a-1][b]['ganancias_netas'])
$scope.data[i][a] = $scope.relatorios[a-1][b]['ganancias_netas'];
}
}
}
Thanks for your help
I just solved with 2 for
First i fill every data space with 0
for (var i = 1; i < $scope.data.length; i++) {
for (var a = 1; a < $scope.data[0].length; a++) {
$scope.data[i][a] = 0;
}
}
The i jus remplace where fecha_emision equal to position 1 of every array.
for (var a = 0; a < $scope.relatorios.length; a++) {
for (var b = 0; b < $scope.relatorios[a].length; b++) {
for (var i = 1; i < $scope.data.length; i++) {
var index = $scope.data[i].indexOf($scope.relatorios[a][b]['fecha_emision']);
if(index >= 0) {
$scope.data[i][a+1] = parseFloat($scope.relatorios[a][b]['ganancias_netas']);
}
}
}
}

Searching a 2D Javascript Array For Value Index

I am trying to write a jQuery that will find the index of a specific value within a 7x7 2D array.
So if the value I am looking for is 0 then I need the function to search the 2D array and once it finds 0 it stores the index of the two indexes.
This is what I have so far, but it returns "0 0" (the initial values set to the variable.
Here is a jsFiddle and the function I have so far:
http://jsfiddle.net/31pj8ydz/1/
$(document).ready( function() {
var items = [[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,0,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7]];
var row = 0;
var line = 0;
for (i = 0; i < 7; ++i) {
for (j = 0; i < 7; ++i) {
if (items[i, j] == '0,') {
row = i;
line = j;
}
}
}
$('.text').text(row + ' ' + line);
});
HTML:
<p class="text"></p>
Your if statement is comparing
if (items[i, j] == '0,')
Accessing is wrong, you should use [i][j].
And your array has values:
[1,2,3,4,5,6,7]
....
Your value '0,' is a string, which will not match numeric values inside the array, meaning that your row and line won't change.
First, you are accessing your array wrong. To access a 2D array, you use the format items[i][j].
Second, your array doesn't contain the value '0'. It doesn't contain any strings. So the row and line variables are never changed.
You should change your if statement to look like this:
if(items[i][j] == 0) {
Notice it is searching for the number 0, not the string '0'.
You access your array with the wrong way. Please just try this one:
items[i][j]
When we have a multidimensional array we access the an element of the array, using array[firstDimensionIndex][secondDimensionIndex]...[nthDimensionIndex].
That being said, you should change the condition in your if statement:
if( items[i][j] === 0 )
Please notice that I have removed the , you had after 0. It isn't needed. Also I have removed the ''. We don't need them also.
There are following problems in the code
1) items[i,j] should be items[i][j].
2) You are comparing it with '0,' it should be 0 or '0', if you are not concerned about type.
3) In your inner for loop you should be incrementing j and testing j as exit condition.
Change your for loop like bellow and it will work
for (i = 0; i < 7; i++) {
for (j = 0; j < 7; j++) {
if (items[i][j] == '0') {
row = i;
line = j;
}
}
}
DEMO
Note:-
1) Better to use === at the place of ==, it checks for type also. As you see with 0=='0' gives true.
2) Better to say i < items.length and j<items[i].length instead of hard-coding it as 7.
var foo;
items.forEach(function(arr, i) {
arr.forEach(function(val, j) {
if (!val) { //0 coerces to false
foo = [i, j];
}
}
}
Here foo will be the last instance of 0 in the 2D array.
You are doing loop wrong
On place of
for (i = 0; i < 7; ++i) {
for (j = 0; i < 7; ++i) {
if (items[i, j] == '0,') {
row = i;
line = j;
}
}
}
use this
for (i = 0; i < 7; i++) {
for (j = 0; j < 7; j++) {
if (items[i][j] == 0) {
row = i;
line = j;
}
}
}
Here is the demo
looks like you are still learning how to program. But here is an algorithm I've made. Analyze it and compare to your code ;)
var itens = [[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,0,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7],
[1,2,3,4,5,6,7]];
var row = null;
var collumn = null;
for (var i = 0; i < itens.length; i++) {
for (var j = 0; j < itens[i].length; j++) {
if (itens[i][j] == 0) {
row = i;
collumn = j;
}
}
}
console.log(row, collumn);

js match serarching with array

I'm trying to get the first date of each 3 names from a list sorted by rows.
The array is dynamic. Without arrays, it works fine...
But from here I can't get it to work. Is there any way to get the array into the match?
var array=new Array();
array[1]='name1';
array[2]='name2';
array[3]='name3';
for (var k = 1; k <= array.length; k++) {
tow = document.getElementById('cal_table');
zap = tow.getElementsByTagName('tr');
for (var i=1; i<=zap.length; i++){
opt0 = zap[i].innerHTML.match(/<td>array[k]<\/td>|<td>.*2012<\/td>/img);
if(opt0.length==2){
alert(opt0);
break
}
}
}
You have to use the RegExp constructor, i.e. new RegExp("<td>" + array[k] + "|<td>.*2012<\/td>", "img").

Adding up all combinations of number in an array

I am trying to write a program in javascript that gets an unspecified number of numbers out of a html textarea and tries all combinations (adding all numbers with eachother) to see if it mathches a number you specified.
Now I can make an array out of the string in the textarea and using for loops I add these up (see below code). The problem how can you do this for an unspecified number of numbers that are to be added up (e.g. adding up 7 different number if you enter 7 numbers in textarea)? I was thinking of using a second array and, which gets the numbers to add up out of the first loop. And then make te lenght of the loop variable by using a for loop with the lenght of the array containing all numbers (lines in my example) as endvalue.
How can I fill in the values of this 2nd array, making sure all combinations are used?
By the way, I wanted this code because I am a auditor. Sometimes a client reverses a couple of amounts in one booking, without any comment. This code will make it a lot easier to check what bookings have been reversed
edit: The awnser of cheeken seems to be working I only have one remark. What if multiple sub sets of your power set added up result in the number you are looking for? e.g.:findSum([1,2,3,4,5],6) can result [1,2,3] but also [2,4] or [1,5]. is it possible to let the function return multiple sub sets?
Found the answer my self :)
I replaced code
return numberSet;
By
document.getElementById("outp").value=document.getElementById("outp").value+ numberSet +"\n";
Thank you very much Cheeken
One more additional question. How do i format the input for parsing that function? The code below doesn't seem to work. inp is the ID of the textarea where the input is (the numbers are seperated with a semicolumn. The variable ge works so there is no problem there (tested it with [1,2,3,4] and it worked. What is wrong with this code?
re edit:
found the solution. The array needed to be parsed as a floating number added this code.`
for (var i=0; i < lines.length; i++) {
lines[i]= parseFloat(lines[i]);
}
findSum(document.getElementById("inp").value.split(";"), ge);
Code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function powerset(arr) {
var ps = [[]];
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(arr[i]));
}
}
return ps;
}
function sum(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++)
total += arr[i];
return total
}
function findSum(numbers, targetSum) {
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
document.getElementById("outp").value=document.getElementById("outp").value+ numberSet +"\n";
}
}
function main()
{
ge= document.getElementById("getal").value;
findSum([1,1,0.5,0.1,0.2,0.2], ge);
}
</script>
</head>
<body>
<input type="button" onclick="main()" value="tel" /><input type="text" id="getal" /><br>
input<br><textarea id="inp" ></textarea><br>
output<br><textarea id="outp" ></textarea><br>
document.getElementById("inp").value.split(";")
</body>
</html>
More concretely, you're looking for a particular sum of each set in the power set of your collection of numbers.
You can accomplish this with the following bit of code.
function powerset(arr) {
var ps = [[]];
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(arr[i]));
}
}
return ps;
}
function sum(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++)
total += arr[i];
return total
}
function findSum(numbers, targetSum) {
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
return numberSet;
}
}
Example invocation:
>> findSum([1,2,3,4,5],6)
[1, 2, 3]
>> findSum([1,2,3,4,5],0)
[]
>> findSum([1,2,3,4,5],11)
[1, 2, 3, 5]
If you'd like to collect all of the subsets whose sum is the value (rather than the first one, as implemented above) you can use the following method.
function findSums(numbers, targetSum) {
var sumSets = [];
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
sumSets.push(numberSet);
}
return sumSets;
}
Example invocation:
>> findSums([1,2,3,4,5],5);
[[2,3],[1,4],[5]]
>> findSums([1,2,3,4,5],0);
[[]]

Categories