JavaScript Nested for showing wrong results - javascript

I am having trouble with this code and can not figure it out. It appears to add to "data" rather than to "ticket" from "data" like it should. Using code in Google Script
function consolidate(){
var data = [[1,1,1,1,1,1],[1,1,1,1,1,1],[1,2,1,2,1,2],[1,2,1,2,1,2],[1,1,1,1,1,1],[1,2,1,2,1,2],[1,1,1,1,1,1],[1,2,1,2,1,2],[1,2,1,2,1,2]];
var ticket = [];
ticket[0] = data[0];
for(var x=0;x<data.length;x++){
for(var i=0;i<ticket.length;i++){
if(ticket[i][0]==data[x][0]&&ticket[i][1]==data[x][1]&&ticket[i][2]==data[x][2]&&ticket[i][4]==data[x][4]){
ticket[i][3]=ticket[i][3]+data[x][3];
ticket[i][5]=ticket[i][5]+data[x][5];
break;
}
}
ticket[i]=data[x];
}
}
my result for data is
[[1, 1, 1, 3, 1, 3], [1, 1, 1, 2, 1, 2], [1, 2, 1, 4, 1, 4], [1, 2, 1, 4, 1, 4], [1, 1, 1, 2, 1, 2], [1, 2, 1, 4, 1, 4], [1, 1, 1, 1, 1, 1], [1, 2, 1, 4, 1, 4], [1, 2, 1, 2, 1, 2]]
but data should not change

function consolidate(){
var data = [[1,1,1,1,1,1],[1,1,1,1,1,1],[1,2,1,2,1,2],
[1,2,1,2,1,2],[1,1,1,1,1,1],[1,2,1,2,1,2],
[1,1,1,1,1,1],[1,2,1,2,1,2],[1,2,1,2,1,2]];
var ticket = [];
ticket[0] = data[0].slice();
for(var x = 0; x < data.length; x++) {
for(var i = 0; i < ticket.length; i++) {
for(var k = 0; k < 5; k++) {
if (ticket[i][k] != data[x][k])
break;
else if (k != 4)
continue;
ticket[i][3] += data[x][3];
ticket[i][5] += data[x][5];
}
}
ticket[i] = data[x].slice();
}
console.log(data);
}
consolidate();

This is where I got and it works. If there is a way to make it better please let me know
function consolidate1(){// put data in here <-----()
var data = [[1,1,1,1,1,1],[2,1,1,1,1,1],[1,1,1,1,1,1],[2,1,1,1,1,1],[1,1,1,1,1,1],[3,1,1,1,1,1],[1,1,1,1,1,1],[3,1,1,1,1,1],[1,1,1,1,1,1]];
var ticket = [];
ticket[0]=[];
ticket[0][0]=data[0][0];
ticket[0][1]=data[0][1];
ticket[0][2]=data[0][2];
ticket[0][3]=data[0][3];
ticket[0][4]=data[0][4];
ticket[0][5]=data[0][5];
for(var x=1;x<data.length;x++){ //get all the unique rows based on columns 0,1,2,4
var indicator = 0;
for(var i=0;i<ticket.length;i++){
if(ticket[i][0]==data[x][0] && ticket[i][1]==data[x][1] && ticket[i][2]==data[x][2] && ticket[i][4]==data[x][4]){
ticket[i][3]=ticket[i][3]+data[x][3];
ticket[i][5]=ticket[i][5]+data[x][5];
indicator = 1;
break;
}
}
if(indicator==0){
ticket[i]=[];
ticket[i][0]=data[x][0];
ticket[i][1]=data[x][1];
ticket[i][2]=data[x][2];
ticket[i][3]=data[x][3];
ticket[i][4]=data[x][4];
ticket[i][5]=data[x][5];
}
}
Logger.log(ticket);
}

Related

Why JS is passing a number into the array as a string?

I'm trying to obtain // [2,6,0,8,4] from the function:
let getValidPassword = arr => {
let x = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
x += arr[i][j];
}
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
However when I run the typeof x, I'm getting a string(I though it was a number) and when I print x I get 26084 instead of [26084]
what witchcraft is this?
I though setting x to [ ] would make the trick...
thank you.
The problem here is that you have declared x=[] but you are modifying it as x += arr[i][j]; as soon as javascript gets to this line. It treats the array as string calling x.toString() internally and appending to that string. For example if you declare an array as a=[] and call a+=1 then a will become "1". In javascript everything is value typed, it doesn't matter what you declare when you assign some value to it or do some operation on the variable, it gets converted to the type of value.
I would recommend you to go through this
let getValidPassword = arr => {
let x = [];
let temp = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
temp.push(arr[i][j]);
}
if(temp.length == arr[i].length)
x = temp.slice();
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
The problem is that you are incrementing your variable, to add an element to an array you need to use the push() method.
Correct code:
let getValidPassword = arr => {
let x = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
x.push(arr[i][j]);
}
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
When you concatenate an array (which is what += is doing) it first converts the array and the value being appended to strings.
In order to add elements to the x array use x.push(arr[i][j]), this will insert them without type conversion.

Retrieve diagonal values from a 2d array

I'm trying to create a function that retrieves the diagonal values from a 2-d array:
input = [
[1, 2, 3, 4],
[5, 1, 2, 3],
[9, 5, 1, 2]
]
output = [[9], [5, 5], [1, 1, 1], [2, 2, 2], [3, 3], [4]]
I'm having trouble figuring out how to manipulate the indices in a nested loop... This is what I'm currently working with:
const diagonalValues = arr => {
let output = new Array(2*input.length);
for (let i = 0; i < output.length; i++) {
output[i] = [];
if (i < input.length) {
for (j = input.length-1; j>i-input.length; --j) {
console.log(i, j)
}
}
}
}
How can I accomplish this?
You could use get number of rows which is just number of arrays and number of columns which is number of elements in each inner array (assuming all arrays have the same number of elements), and based on that calculate the diagonal matrix.
const input = [
[1, 2, 3, 4],
[5, 1, 2, 3],
[9, 5, 1, 2]
]
const rows = input.length;
const columns = input[0].length;
const total = columns + rows - 1;
const result = [];
for (let i = rows - 1; i >= 0; i--) {
const row = input[i];
for (let j = 0; j < columns; j++) {
const el = input[i][j];
const pos = j + rows - i - 1;
if (!result[pos]) {
result[pos] = []
}
result[pos].unshift(el)
}
}
console.log(JSON.stringify(result))
You can do the same with reduceRight and forEach methods.
let input = [
[1, 2, 3, 4, 4],
[5, 1, 2, 8, 3],
[9, 5, 1, 2, 2],
[9, 5, 1, 2, 1]
]
const result = input.reduceRight((r, a, i) => {
a.forEach((e, j) => {
const pos = j + (input.length - i - 1)
if(!r[pos]) r[pos] = []
r[pos].unshift(e)
})
return r;
}, []);
console.log(JSON.stringify(result))
You can use this algorithm to retrieve the diagonal values from 2d-input array.
const input = [
[1, 2, 3, 4],
[5, 1, 2, 3],
[9, 5, 1, 2]]
let output = []
input.forEach(res => {
res.forEach(resp => {
// if length of array is equel to 1
if (output.filter(x => x == resp).length > 0) {
output.filter(x => x == resp)[0].push(resp)
//if length of array is greater than 1
} else if (output.filter(x => x[0] == resp).length > 0) {
output.filter(x => x[0] == resp)[0].push(resp)
} else {
let temp = []
temp.push(resp)
output.push(temp)
}
})
})
output.forEach(o => console.log(JSON.stringify(o)));
let input = [
[1, 2, 3, 4],
[5, 1, 2, 8],
[9, 5, 1, 2],
[9, 5, 1, 2],
[9, 5, 1, 2],
];
let out = [];
for (let i = 1 - input.length; i < input[0].length; i++) {
let o = [];
let y = Math.max(-i, 0);
let x = Math.max(i, 0);
while (x < input[0].length && y < input.length)
o.push(input[y++][x++]);
out.push(o)
}
out.forEach(o => console.log(JSON.stringify(o)));

Iterate through array to find values that equal a specified sum

I am trying to write a function that will yield the following output:
// Required sum
console.log([3, 4, 2, 1, 2, 3, 6, 0].elementsTheSumTo(6)) // [ [3, 3], [4, 2], [6, 0] ]
console.log([7, 0, 5, 8, 0, 0, 7, 7].elementsThatSumTo(7)) // [ [7, 0], [0, 7], [0, 7], [0, 7] ]
I've tried with,
Array.prototype.elementsThatSumTo = n => {
let result = [];
for (let i = 0; i < this.length; i++) {
for (let j = 0; j < this.length; j++) {
if (j !== i && (this[i] + this[j] === n) {
result.push([ this[i], this[j] ]);
}
}
}
return result;
}
But that's yielding unexpected behavior. I was also thinking of using reduce, but that didn't seem to work either. Not sure how to figure this one out.
You need to remove the elements from the array when matches are found, which can be done with splice. You also need to use a full-fledged function to access the this, the array instance:
Array.prototype.elementsThatSumTo = function(n) {
const arr = this.slice(); // avoid mutating the input array
const result = [];
while (arr.length) {
const num1 = arr.shift();
const num2Index = arr.findIndex(num => num1 + num === n);
if (num2Index === -1) {
continue;
}
result.push([num1, arr[num2Index]]);
arr.splice(num2Index, 1);
}
return result;
}
console.log([3, 4, 2, 1, 2, 3, 6, 0].elementsThatSumTo(6)) // [ [3, 2], [4, 2], [6, 0] ]
console.log([7, 0, 5, 8, 0, 0, 7, 7].elementsThatSumTo(7)) // [ [7, 0], [0, 7], [0, 7], [0, 7] ]
Keep in mind that mutating built-in prototypes is very bad practice. If possible, consider using a standalone function instead:
const elementsThatSumTo = (arrInit, n) => {
const arr = arrInit.slice(); // avoid mutating the input array
const result = [];
while (arr.length) {
const num1 = arr.shift();
const num2Index = arr.findIndex(num => num1 + num === n);
if (num2Index === -1) {
continue;
}
result.push([num1, arr[num2Index]]);
arr.splice(num2Index, 1);
}
return result;
}
console.log(elementsThatSumTo([3, 4, 2, 1, 2, 3, 6, 0], 6)) // [ [3, 2], [4, 2], [6, 0] ]
console.log(elementsThatSumTo([7, 0, 5, 8, 0, 0, 7, 7], 7)) // [ [7, 0], [0, 7], [0, 7], [0, 7] ]
You could take a Map and store the visited elements and cound the occurence.
Array.prototype.elementsThatSumTo = function (sum) {
var map = new Map,
i, l, v
result = [];
for (i = 0, l = this.length; i < l; i++) {
v = this[i];
if (map.get(v)) {
map.set(v, map.get(v) - 1);
result.push([sum - v, v]);
continue
}
map.set(sum - v, (map.get(sum - v) || 0) + 1);
}
return result;
}
console.log([3, 4, 2, 1, 2, 3, 6, 0].elementsThatSumTo(6)) // [ [3, 2], [4, 2], [6, 0] ]
console.log([7, 0, 5, 8, 0, 0, 7, 7].elementsThatSumTo(7)) // [ [7, 0], [0, 7], [0, 7], [0, 7] ]
Array.prototype.elementsThatSumTo = function(n) {
var result = [],
len = this.length;
for (var i = 0; i < len - 1; i++)
for (var j = i + 1; j < len; j++)
if (this[i] + this[j] == n)
result.push([this[i], this[j]]);
return result;
}
console.log([3, 4, 2, 1, 2, 3, 6, 0].elementsThatSumTo(6))
That's because for every number you are also seeing for the combinations that are already covered. Just change (j=0) to (j=(i+1)) in your code it will work fine and you can also ignore the check(j==i) then.
Array.prototype.elementsThatSumTo = function(n) {
let result = [];
for (let i = 0; i < this.length; i++) {
for (let j = (i+1); j < this.length; j++) {
if (this[i] + this[j] === n) {
result.push([ this[i], this[j] ]);
}
}
}
return result;
}
console.log([3, 4, 2, 1, 2, 3, 6, 0].elementsThatSumTo(6)) // [ [3, 3], [4, 2], [6, 0] ]
console.log([7, 0, 5, 8, 0, 0, 7, 7].elementsThatSumTo(7)) // [ [7, 0], [0, 7], [0, 7], [0, 7] ]

Array conversion?

I'm really new to javascript, and when trying to achieve the following I stumbled upon some problems. I tried searching the forum - and a problem like this is probably something that has been solved before, but I don't know what to search for. This is also the reason for the extremely creative title:/
Anyhow - this is my current code:
var arraylength = 4;
var originalarray = new Array(new Array);
var originalarray = {
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]
[4, 4, 4, 4]
}
convertarray(originalarray, arraylength);
function convertarray(originalarray, arraylength){
var converedtarray = new Array(new Array);
var temparray = new Array;
temparray.length = arraylength;
for (h = 0; h < arraylength; h++) {
var temparray = [];
var temparray = originalarray[h].split('');
for (i = 0; i < arraylength; i++) {
converedtarray[h][i] = temparray[i];
}
}
return convertedarray;
}
I am not entirely sure if the code speaks for itself, but this is pseudo for what I want to achieve;
originalarray = 1111, 2222, 3333, 4444
converedtarray = 1234, 1324, 1234, 1234
Can someone tell me what part I've missed or give me a hint of what I can do?
Because I'm getting "TypeError: undefined is not an object" at this part:
converedtarray[h][i] = temparray[i];
I am by no means a professional coder - I know the code isn't pretty, but this is more or less the result of trial-and error... More error than trial actually.
Thank you in advance for your answer!
A possible solution:
var arraylength = 4;
var originalarray = [
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
];
function convertarray(originalarray, arraylength) {
var result = [];
for (h = 0; h < arraylength; h++) {
result.push(
originalarray.map(function(subarray) {
return subarray[h];
})
);
}
return result;
}
console.log(
convertarray(originalarray, arraylength)
);
There are a few problems with your code. Firstly if you want a nXn array you have defined originalarray wrong. Second new Array(new Array) won't declare an array of array for you if that is what you were thinking. You will need two loops here as you have already figured out the first one for maintaining columns and the second one for rows.
var arraylength = 4;
var originalarray = new Array();
var originalarray = [
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]
]
console.log(convertarray(originalarray, arraylength));
function convertarray(originalarray, arraylength){
var converedtarray = new Array();
for (h = 0; h < arraylength; h++) {
converedtarray[h] = [];
for (i = 0; i < arraylength; i++) {
converedtarray[h].push(originalarray[i][h]);
}
}
return converedtarray;
}

Javascript Basic Logic - print each three and four cycle from 1 to n

I want to see the output like
[0, 1, 2]
[3, 4, 5, 6]
[7, 8, 9]
[10, 11, 12, 13]
[14, 15, 16]
...
recognize every three(a cycle) and four(b cycle) to do something.
I have only figure out some bad way I think like following:
var arr = [];
function a(n) {
var eachCycle = 7;
var aCycle = 3;
var bCycle = 0;
arr.push(0);
for (var i = 1; i < n; i += 1) {
if (i % eachCycle === aCycle || i % eachCycle === bCycle) {
if(i % eachCycle === aCycle) {
// print three column
} else if(i % eachCycle === bCycle) {
// print four column
}
console.log(arr);
arr.length = 0;
}
arr.push(i)
}
}
is there any good idea to improve this function for the output !?
Thanks
How about this:
function a(n)
{
// keep track of all the cycles
var total = [];
// hold values for the current cycle
var temp = [];
// cycle sizes
var cycleSizes = [3, 4];
// index of the current cycle
var currentCycleIndex = 0;
// iterate through numbers
for(var i = 0; i < n; ++i)
{
// push the value into the temp
temp.push(i);
// if the length of the temp array is the length we want for the current cycle then
if(temp.length == cycleSizes[currentCycleIndex])
{
// save the cycle data
total.push(temp);
// reset the cycle
temp = [];
// change the cycle
currentCycleIndex = currentCycleIndex ^ 1;
}
}
return total;
}
a(9);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8]
];
a(17);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8, 9],
[10, 11, 12, 13],
[14, 15, 16],
];

Categories

Resources