Array Transpose: Error reading property from "Undefined" - javascript

Getting an error message for the below code that works to get Values from several cells in my order entry tab named POTemplate and log them in my POHistory tab the serves to compile a list of all order detail entries. As the debugger gets to the bottom of the below code, I get an error message stating: "Cannot Read Property 0.0 from Undefined"
function submit() {
var app = SpreadsheetApp;
var tplSheet = app.getActiveSpreadsheet().getSheetByName("POTemplate");
var tplFRow = 22, tplLRow = tplSheet.getLastRow();
var tplRowsNum = tplLRow - tplFRow + 1;
var tplFCol = 1, tplLCol = 16;
var tplColsNum = tplLCol - tplFCol + 1;
var rangeData = tplSheet.getRange(22, 1, 5, 15).getValues();
var colIndexes = [0, 3, 10, 12, 15];
var fData = filterByIndexes(rangeData, colIndexes);
var target = "POHistory";
var targetSheet = app.getActiveSpreadsheet().getSheetByName(target);
var tgtRow = targetSheet.getLastRow() + 1;
var tgtRowsNum = fData.length - tgtRow + 1;
var tgtCol = 1;
var tgtColsNum = fData[0].length - 1 + 1;
targetSheet.getRange(tgtRow, tgtCol, tgtRowsNum,
tgtColsNum).setValues(fData);
}
function filterByIndexes(twoDArr, indexArr) {
var fData = [];
twoDArr = twoDArr.transpose();
for(var i = 0; i < indexArr.length; i++) {
fData.push(twoDArr[indexArr[i]]);
}
return fData.transpose();
}
Array.prototype.transpose = function() {
var a = this,
w = a.length ? a.length : 0,
h = a[0] instanceof Array ? a[0].length : 0;
if (h === 0 || w === 0) {return [];}
var i, j, t = [];
for (i = 0; i < h; i++) {
t[i] = [];
for (j = 0; j < w; j++) {
t[i][j] = a[j][i];
}
}
return t;
}

Related

Why is my Javascript view on a buffer all zeroes?

I create a buffer and then a Uint8Array on it, but the array does not have any values. I would expect it to have the values of the buffer. This is an easily reproducible example:
var buf = new ArrayBuffer(32);
for (var index = 0; index < 32; index++) buf[index] = index;
console.log(buf);
var arr = new Uint8Array(buf);
console.log(arr);
The thing I tried in reality is a date format converter like this:
//Buffers and views
function convertDateTimeToFormat(date, initialFormat, endFormat) {
var buf = new ArrayBuffer(14);
var result = new Uint8Array(buf);
console.log(date);
var initialPositions = {};
var endPositions = {};
var sizeSoFar = 0;
for (var c of initialFormat) {
if (c === 'y') {
initialPositions.y = new Uint32Array(date, sizeSoFar, 1);
} else {
initialPositions[c] = new Uint8Array(date, sizeSoFar, 2);
}
sizeSoFar += ((c === 'y') ? 4 : 2);
}
sizeSoFar = 0;
for (var c of endFormat) {
if (c === 'y') {
endPositions.y = new Uint32Array(buf, sizeSoFar, 1);
} else {
endPositions[c] = new Uint8Array(buf, sizeSoFar, 2);
}
sizeSoFar += ((c === 'y') ? 4 : 2);
}
for (var key in initialPositions) {
var limit = (key === 'y') ? 4 : 2;
for (var index = 0; index < limit; index++) endPositions[c][index] = initialPositions[c][index];
}
return result;
}
//2019-03-01 13:03:50
var buf = new ArrayBuffer( 14 );
buf[0] = 2;
buf[1] = 0;
buf[2] = 1;
buf[3] = 9;
buf[4] = 0;
buf[5] = 3;
buf[6] = 0;
buf[7] = 1;
buf[8] = 1;
buf[9] = 3;
buf[10] = 0;
buf[11] = 3
buf[12] = 5;
buf[13] = 0;
console.log(convertDateTimeToFormat(buf, "yMdHms", "yMdHms"));
console.log(convertDateTimeToFormat(buf, "yMdHms", "MdyHms"));
But due to the behavior I described at the start of this question, the results are all zeroes.
This works but it's not elegant, because it expects a date format and if I am to ensure that the input is agnostic to date formats, then the code will become very complicated:
//Buffers and views
var results = {};
var buf = new ArrayBuffer( 4 );
results.uint32 = new Uint32Array(buf);
results.int8 = new Uint8Array(buf);
results.uint8 = new Int8Array(buf);
results.int8[2] = -1;
console.log(results);
results.int8[2] = 0;
results.int8[1] = -1;
console.log(results);
results.int8[1] = 0;
results.int8[0] = -1;
console.log(results);
//Buffers and views
function convertDateTimeToFormat(date, format) {
var buf = new ArrayBuffer(14);
var result = new Uint8Array(buf);
var positions = {
y: 0,
M: 4,
d: 6,
H: 8,
m: 10,
s: 12
};
for (var index = 0; index < 14; index++) {
result[index] = date[positions[format[index]]++];
}
return result.join("");
}
var results = {};
//2019-03-01 13:03:50
var buf = new ArrayBuffer( 14 );
buf[0] = 2;
buf[1] = 0;
buf[2] = 1;
buf[3] = 9;
buf[4] = 0;
buf[5] = 3;
buf[6] = 0;
buf[7] = 1;
buf[8] = 1;
buf[9] = 3;
buf[10] = 0;
buf[11] = 3
buf[12] = 5;
buf[13] = 0;
console.log(convertDateTimeToFormat(buf, "yyyyMMddHHmmss"));
console.log(convertDateTimeToFormat(buf, "MMddyyyyHHmmss"));
An ArrayBuffer is just an object representing a slice of memory. It has a fixed size, that's it. It does not have properties that represent the contents, for that you'll need a typed array as a view on the buffer. Your code is just assigning properties to the buffer which works as it is an object, but it doesn't actually manipulate the byte contents which stay zero.
Don't explicitly instantiate the buffer at all if you don't need it. Just write
var arr = new Uint8Array(32);
for (var index = 0; index < 32; index++) arr[index] = index;
console.log(arr.buffer);
console.log(arr);
In your actual code, it seems you want to use an Uint8Array to store the numbers in individual bytes. And probably you should just pass that array instead of the underlying buffer into the function.
You can create it like this:
const arr = Uint8Array.of(2,0,1,9,0,3,0,1,1,3,0,3,5,0);
// or Uint8Array.from([2,0,1,9,0,3,0,1,1,3,0,3,5,0])
// or new Uint8Array(2,0,1,9,0,3,0,1,1,3,0,3,5,0]);
const buf = arr.buffer;

How do Object and some Key in square brackets work?

Can somebody explain how does seen[item] work?
var a = ["a","a","a","b","b","c","D","D","e",6,6,7,8,9,"a",'b','a',"c","","","",""];
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 0;
for(var i = 0; i < len; i++) {
var item = a[i];
if(seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
var e = uniq_fast(a);
console.log(e);
It returns undefined everytime:
var a = [1,1,1,1,1,2,2,3,4,4,4,4,4,5,"a",'b','a',"c"];
for(var i = 0; i < a.length; i++) {
var seen = {};
var item = a[i];
var x = seen[item];
console.log(x);
}
I've added comments to your code, you can also check google Developer tools (or other browser equivalent) set breakpoint before for loop and go step by step to see the value of each variable.
var a = ["a","a","a","b","b","c","D","D","e",6,6,7,8,9,"a",'b','a',"c","","","",""];
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 0;
// if i == 0;
for(var i = 0; i < len; i++) {
var item = a[i]; // item is "a" because that's first item in array
if(seen[item] !== 1) {
seen[item] = 1; // seen is {"a": 1} it's the same as seen['a'] = 1
out[j++] = item;
}
}
return out;
}
in your second code:
var a = ["a","a","a","b","b","c","D","D","e",6,6,7,8,9,"a",'b','a',"c","","","",""];
for(var i = 0; i < a.length; i++) {
var seen = {}; // you have empty object
var item = a[i]; // item is "a"
console.log(seen[item]); // this is undefined because seen["a"] is empty,
// you never adding anything to seen
}
In essence it's not more than
object['a'] = object.a

Why do I get a NaN value and the end of my rubiks cube scramble generator when I remove duplicates?

I am developing a Rubik cube app for fitbit versa and I run into the problem of removing duplicates from arrays as I get a NaN error when combining the arrays once the duplicates have been removed from the end of the list and it only happens when I splice at the end of the array and I cant figure out the reason why this isnt working
function getScramble(number_of_moves, faces, modifiers, scramble_faces, scramble_modifiers, scramble) {
for (var i = 0; i < number_of_moves; i++) {
var sample = faces[Math.floor(Math.random() * faces.length)];
var mod = modifiers[Math.floor(Math.random() * modifiers.length)];
scramble_faces[i] = sample;
scramble_modifiers[i] = mod;
if (scramble_faces[i] == scramble_faces[i - 1]) {
scramble_faces[i] = faces[Math.floor(Math.random() * faces.length)];
}
}
removeDuplicates(scramble_faces, scramble_modifiers)
for (var i = 0; i < number_of_moves - 2; i++) {
scramble[i] = scramble_faces[i] + scramble_modifiers[i]
}
console.log(scramble);
let demotext = document.getElementById("demotext");
demotext.text = scramble;
scramble = [];
scramble_faces = [];
scramble_modifiers = [];
}
function threebythree() {
var faces = ["U", "D", "L", "R", "F", "B"];
var modifiers = ["", "'", "2"];
var scramble_faces = [];
var scramble_modifiers = [];
var scramble = [];
var number_of_moves = 22;
let Title1 = document.getElementById("title");
Title1.text = "3x3"
getScramble(number_of_moves, faces, modifiers, scramble_faces, scramble_modifiers, scramble, Title1)
}
function removeDuplicates(arr, arr2, number_of_moves) {
var t = 0;
var new_arr = arr;
var new_arr2 = arr2;
for (var i = new_arr.length - 1; i >= 0; i--) {
if (new_arr[i] === new_arr[i - 1]) {
new_arr.splice(i, 1);
new_arr2.splice(i, 1);
}
}
arr = new_arr;
arr2 = new_arr2;
new_arr = [];
new_arr2 = [];
new_arr.pop();
new_arr2.pop();
console.log(arr);
console.log(arr2);
}
The lengths of scramble_faces and scramble_modifiers is initially number_of_moves. But after you remove duplicates from them, it can be shorter. But you still use number_of_moves in the limit in the next for loop. So when you try to add the elements that no longer exist you get undefined. undefined + undefined == NaN.
You should use the length of one of the arrays instead:
function getScramble(number_of_moves, faces, modifiers, scramble_faces, scramble_modifiers, scramble) {
for (var i = 0; i < number_of_moves; i++) {
var sample = faces[Math.floor(Math.random() * faces.length)];
var mod = modifiers[Math.floor(Math.random() * modifiers.length)];
scramble_faces[i] = sample;
scramble_modifiers[i] = mod;
if (scramble_faces[i] == scramble_faces[i - 1]) {
scramble_faces[i] = faces[Math.floor(Math.random() * faces.length)];
}
}
removeDuplicates(scramble_faces, scramble_modifiers)
for (var i = 0; i < scramble_faces.length - 2; i++) {
scramble[i] = scramble_faces[i] + scramble_modifiers[i]
}
console.log(scramble);
let demotext = document.getElementById("demotext");
demotext.text = scramble;
scramble = [];
scramble_faces = [];
scramble_modifiers = [];
}

translation matrix in javascript

I have a translation matrix in javascript which I can't seem to get working. If I have a single matrix I can access the different levels OK using the method I have used but as soon as I try to multiply it with another matrix I get an error: Internal error setting variable. Thanks for your comments.
function funct(number, number1) {
var matrixATranslate = new Array();
var matrixBTranslate = new Array();
var matrixCTranslate = new Array();
var matrixATranslate = [
[1, number, 0, number1],
[number1, 1, 0, 0],
[0, 0, 0, 0]
];
var matrixBTranslate = [
[number],
[number1],
[0],
[1]
];
var row = 3, col = 4, add = 4;
for (var i = 0; i < row; i++) {
for (var j = 0; j < col; j++) {
var sum = 0;
for (var k = 0; k < add; k++) {
sum += matrixATranslate[i, k] * matrixBTranslate[k, j];
}
matrixCTranslate[i, j] = sum;
}
}
Vars.transformedPoint.x = matrixCTranslate[0][0];
Vars.transformedPoint.y = matrixCTranslate[0][0];
return Vars.transformedPoint;
}
Vars.transformedPoint = funct(10, 20);
Got the working code here.
var matrixATranslate = new Array();
var matrixBTranslate = new Array();
var matrixCTranslate = new Array();
for(var i = 0; i < 4; i++) {
for(var j = 0; j < 4; j++) {
matrixCTranslate[i,j] = [ ];
}
}
var matrixATranslate = [
[5,6,7,8],
[10,20,30,40],
[100,200,300,400]
];
var matrixBTranslate = [5,6,7,8];
matrixCTranslate[0][0]=matrixATranslate[2][3] * matrixBTranslate[0,0];
var varA=matrixCTranslate[0,0];
console.log(varA)

Dijkstra's Algorithm in Javascript Maze Implementation

I'm trying to use Dijkstra's Algorithm to path find every position of a maze back to a specific point.
I found a JavaScript version of Dijkstra's Algorithm here:
https://github.com/bm1362/dijkstra-js/blob/master/nodes.js
(Thank you bm1362!)
The way I've approached creating the maze graph is as follows:
// the maze
var maze =
[[1, 1, 1, 1],
[1, 0, 0, 0],
[1, 0, 0, 0],
[1, 1, 1, 1]];
maze2 = [];
var i = 0;
var mazeSize = 30;
for (var x = 0; x < maze[0].length; x++) {
for (var y = 0; y < maze[0].length; y++) {
if (maze[x][y] == 1) {
nodes.push(new node);
nodes[i].setPos((x) * (maze[0].length + 100), (y) * ((maze[0].length + 100)))
nodes[i].tmppos = [x, y];
nodes[i].id = i;
maze2[x + ',' + y] = nodes[i];
i++;
}
}
}
//sort nodes in order of x position
var sortedNodes = quickSort(nodes);
//var sortedNodes = nodes;
for (var i = 0; i < sortedNodes.length; i++) {
sortedNodes[i].number = i;
var n1 = sortedNodes[i];
var up = {}, down = {}, left = {}, right = {};
var pos = [];
up.x = n1.tmppos[0];
up.y = n1.tmppos[1] - 1;
pos.push(up);
down.x = n1.tmppos[0];
down.y = n1.tmppos[1] + 1;
pos.push(down);
left.x = n1.tmppos[0] - 1;
left.y = n1.tmppos[1];
pos.push(left);
right.x = n1.tmppos[0] + 1;
right.y = n1.tmppos[1];
pos.push(right);
for (var m = 0; m < pos.length; m++) {
if (maze[pos[m].x] != undefined && maze[pos[m].x][pos[m].y] != undefined && maze[pos[m].x][pos[m].y] == 1) {
var n2 = maze2[pos[m].x + ',' + pos[m].y];
var dist = calcDist(n1, n2);
sortedNodes[i].addConnection(n2);
connections.push({
a: n1,
b: n2,
dist: dist
})
}
}
}
The issue that I'm having is even though all the nodes do seem to have a connection, when the algorithm runs, some of the nodes do not get a parent set. But I've tried many different ways and I still cannot get it to set all the parents.
I've created a JS fiddle here: http://jsfiddle.net/XcdCr/3/
Any help would be greatly appreciated.

Categories