Javascript ternary condition operator not working as expected - javascript

I'm making a Row class for a block game I'm creating. I currently have this code for the class:
function Row(size, rowNum, state) {
this.size = size;
this.rowNum = rowNum;
this.cells = state ? this.fromState(state) : this.empty();
}
Row.prototype.empty = function () {
var cells = [];
for (var x = 0; x < this.size; x++) {
cells.push(null);
}
return cells;
};
Row.prototype.fromState = function (state) {
var cells = [];
for (var x = 0; x < this.size; x++) {
var tile = state[this.rowNum][x];
cells.push(tile ? new Tile(tile.position, tile.value) : null);
}
return cells;
};
I got 'position is undefined' error in tile.js. I found this was because the variable tile was null (and so tile.position was undefined). But then, I realized I already had the ternary operator, which, supposedly, already knows that tile is null then pushes null instead of pushing new Tile(tile.position, tile.value). It appears that the ternary operator is not working as expected.
Why is this happening and how do I fix it?
Edit: For clarity: this is my constructor for Tile:
function Tile(position, value) {
this.x = position.x; // This is the line where I am getting the error
this.y = position.y;
this.value = value;
this.previousPosition = null;
this.mergedFrom = null;
}
And the actual error:
TypeError: position is undefined

Related

Algorithm to calculate if 'n' or more intervals intersect & the total of the respective intersections

I need help developing a weird algorithm. I have a JavaScript object containing people and an array for each person of start and end time intervals in milliseconds:
var person = [
(1533242595, 1533242999),
(1533242595, 1533242999),
(1533242595, 1533242999)
]
I need to determine if any intervals intersect/overlap, but for n or more intersections (for example, determining if 4+ intervals overlap) and calculate the total sum of the n or more intersecting intervals.
A function that takes a n parameter and the person object would be perfect.
First the person must be defined as list of lists:
var person = [
[1533242595, 1533242999],
[1533242595, 1533242999],
[1533242595, 1533242999]
];
Here you can find a sample of function:
function limit_intersection(limit, person) {
var arrayLength = person.length;
var intersections = 0;
var intersectionsum = 0;
var min, max = 0;
var tmp;
var intervals = [];
for (var i = 0; i < arrayLength-1; i++) {
if(person[i][0] > person[i][1]) {
tmp = person[i][1];
person[i][1] = person[i][0];
person[i][0] = tmp;
}
for (var j = i+1; j < arrayLength; j++) {
if(person[j][0] > person[j][1]) {
tmp = person[j][1];
person[j][1] = person[j][0];
person[j][0] = tmp;
}
min = 0;
max = 0;
if(person[i][1] <= person[j][0] || person[i][0] >= person[j][1]){
// no intersection
continue;
}
intersections +=1;
if(person[i][0] >= person[j][0]) {
min = person[i][0];
} else {
min = person[j][0];
}
if(person[i][1] >= person[j][1]) {
max = person[j][1];
} else {
max = person[i][1];
}
intervals.push([min,max]);
intersectionsum += max-min;
}
}
return {'n' : intersections, 'sum' : intersectionsum, 'intervals' : intervals};
}
An here the working demo on jsfiddle.net
Are you sure that's how your data is structured? Because that does not look like a Javascript object to me, correct me if I'm wrong.
Break your code in to bite sized problems. What is an overlap? How do we check if two intervals overlap each other? When you make that function, use that to loop through your person intervals. Make a variable that contains the sum of the matches and return that.
function overlaps(startX, endX, startY, endY) {
if(endX < startY || endY < startX) return false;
return true;
}
console.log(overlaps(1,2,1,4)) // true
console.log(overlaps(10,20,1,11)) // true
console.log(overlaps(1,2,3,4)) // false
console.log(overlaps(4,3,2,1)) // false
Now find a way to loop over your persons checking for overlaps with this bite sized function.
Edited, here's an example of answer with bite-sized readable functions instead of the spagetti code in the selected answer:
// Check if two intervals overlap
function overlaps(startX, endX, startY, endY) {
if(endX < startY || endY < startX) return false;
return true;
}
// Check how many times two person arrays overlap
function comparePersons(person1, person2){
var matches = 0;
person1.forEach(function(elementX) {
person2.forEach(function(elementY) {
if(overlaps(
elementX[0],elementX[1],
elementY[0],elementY[1]
)) matches +=1
});
});
return matches;
}
// Check how many times all persons overlap with another
function compareAll(persons, n){
var totalMatches = 0;
persons.forEach(function(element, index1) {
var compareMatches = 0;
persons.forEach(function(compareElement, index2) {
if(index1 !== index2) {
compareMatches += comparePersons(element, compareElement)
}
});
if(compareMatches >= n) totalMatches += 1;
});
return totalMatches;
}
// Create persons to test
var person1 = [
[10,20],
[100,200]
]
var person2 = [
[1,2000],
[50,1000]
]
var person3 = [
[10,200],
[0,1],
[1000,2000],
[100,2000]
]
// Create one array with all persons
var allPersons = [
person1, person2, person3
]
// Test by console logging
console.log(compareAll(allPersons, 5));

scriptProcessorNode.onaudioprocess not able to access global variables

I am building class around a scriptProcessorNode oscillator. I have wrapped my onaudioprocess event handler in a function Gendy.prototype.process. I can access global variables and functions from within this wrapper function, but they are not accessible from within the onaudioprocess function.
I devised a work around for the properties, to redefine them in the wrapper function, but this doesn't work when trying to call another method, a random walk method, with this.walk().
Here is my code:
Gendy.prototype.process = function(){
var point = 0;
var index = 0;
var y = 0;
var breakpoint = this.breakpoint;
var freq = this.freq;
var walk = this.walk();
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
var outputBuffer = audioProcessingEvent.outputBuffer;
var outputData = outputBuffer.getChannelData(0);
for(var j = 0; j < outputData.length;j++){
// linearly interpolate between the new breakpoint positions
// get the interp point by comparing index to the x distance
var lerp = (index - breakpoint[point].x) / (breakpoint[point+1].x - breakpoint[point].x);
y = lerp * (breakpoint[point+1].y - breakpoint[point].y) + breakpoint[point].y;
if(point < breakpoint.length && index >= breakpoint[point+1].x) {
point++;
}
outputData[j] = y;
index+=freq;
if(index >= breakpoint[breakpoint.length-1].x){
index = 0;
point = 0;
walk();
}
}
}
}
This makes sound, but returns the errors:
Uncaught TypeError: walk is not a function
for few lines and then
Uncaught TypeError: undefined is not a function
forever.
Is this a bug with the scriptProcessorNode? Any insight would be appreciated!
no bug in scriptProcessorNode, the issue is the below line:
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
the this varible inside the onaudioprocess would refer to this.scriptNode object by default, you can handle it in one of two ways:
Use bind( as you have done in your answer):
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
...
}.bind(this)
use a local variable to hold the value of this, and use that local variable in place of this:
var self = this;
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
...
I was able to access this from within the onaudioprocess function by attaching .bind(this) to it.
Here is the code:
Gendy.prototype.process = function(){
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
var outputBuffer = audioProcessingEvent.outputBuffer;
var outputData = outputBuffer.getChannelData(0);
for(var j = 0; j < outputData.length;j++){
// linearly interpolate between the new breakpoint positions
// get the interp point by comparing index to the x distance
var lerp = (this.index - this.breakpoint[this.point].x) / (this.breakpoint[this.point+1].x - this.breakpoint[this.point].x);
this.y = lerp * (this.breakpoint[this.point+1].y - this.breakpoint[this.point].y) + this.breakpoint[this.point].y;
if(this.point < this.breakpoint.length && this.index >= this.breakpoint[this.point+1].x) {
this.point++;
}
outputData[j] = this.y;
this.index+=this.freq;
if(this.index >= this.breakpoint[this.breakpoint.length-1].x){
this.index = 0;
this.point = 0;
this.walk();
}
}
}.bind(this);
}

JavaScript: variable within an object is not defined

I'm having problems when trying to store a 2D-array in an object variable.
var prTClass = {
prT: Create2DArray(5,8),
setPriceT: function(i,j,price){
prT[i][j] = price;
},
...
}
Create2DArray() is not throwing any error, and the code is this:
function Create2DArray(rows,columns) {
var mat = [];
for(var x = 0; x < rows; x++){
mat[x] = [];
for(var y = 0; y < columns; y++){
mat[x][y] = 'X';
}
}
return mat;
}
The message error I'm getting is "Uncaught ReferenceError: prT is not defined".
I also tried to instantiate the variable with an init() function, like this:
prT: [],
init: function(){
this.prT=Create2DArray(5,8);
},
What's the problem? Thank you.
You're lacking this. You can never access prT as just prT. You must always access it as either this.prT from within the context of that object, or prTClass.prT from outside.

FOR LOOP in Angular Service NOT Working - While Loop Works

I've worked around this problem with a while loop
but thought I'd explain it here - because it seems odd
I tried iterating through a string in a service using a for loop, but cannot get it to work
When service defined like this
.service('xtratxt', function()
{
var x = 0;
var a = "";
this.convert = function(srctxt)
{
this.a = "";
this.x = 0;
for (this.x=0; this.x++; this.x<srctxt.length)
{
this.a = ans + "X";
}
return ans;
};
})
if I call this in my controller with
$scope.newvalu = xtratxt.convert("Hello");
I should get back a string of X's Eg XXXXX
Instead I get an empty string ""
If I change to a while loop - no problems works a treat
Anyone know why ?
I get no errors in the console either.
AFAIK it doesn't seem to enter the for loop at all
this.convert = function (srctxt) {
var a = "", x = 0, ans = '';
for (x = 0; x < srctxt.length; x++) {
ans += "X";
}
return ans;
};
Shorter version
var str = 'abcde';
str.replace(/\w/gi, 'X');

can't convert undefined to object in javascript

Update: I have added the fiddle. Please refer here. use web console for error.
I am writing a code for traveling salesman problem. Here is the code :
var ind =[]; //values selected
var cp =[];
var X;
var Y;
var tour = [];
// no values selected in the starting
for(j=0;j<friends_cnt;j++) {
ind[j] = 0;
}
// distances at i,i infinity
for(i=0;i<friends_cnt;i++) {
distance[i][i] = 9999999999999;
}
var k = 0;
var X = 0;
tour[k] = X;
ind[X] = 1;
var i =1;
while(i<friends_cnt && ind[i] === 0) {
var min = 9999999999999;
// finding minimum of the undeleted values
for(j=0;j<friends_cnt;j++) {
if(ind[j] === 0) {
if(distance[X][j] < min) {
min = distance[X][j];
Y = j; // y is the min city
}
}
}
k = k+1; // counter for the starting city
tour[k] = Y; //city added
ind[Y] = 1;
X = Y;
i++;
}
k = k+1;
tour[k] = tour[1];
for(var q=0;q<k+1;q++) {
console.log(tour[q]);
}
});
});
now here whenever i run my program, it shows an error
TypeError: can't convert undefined to object
in the line
var min = 9999999999999;
My question is that is this because JavaScript cant handle large numbers or something else ?
Javascript's max number is 1.7976931348623157e+308 (aka the var Number.MAX_VALUE), so that shouldn't be an issue.
If you are trying to access an object of an object, it won't work.
You have distance[X][j]. That tries to access key j of distance[X]. To fix this, define distance[X] as an object:
distance[X] = [];
Other example:
var distance = [];
distance[i]
//undefined;
distance[i][i]
//syntax error
distance[i] = [];
distance[i][i]
//undefined;
For 2D arrays, see this question.
The problem is actually here:
distance[i][i] = 9999999999999;
If distance is undefined or an empty array, that statement will fail. This should fix it:
var distance = []; // <-- this is missing from the top of your code
// ...
if (!distance[i]) {
distance[i] = [];
}
distance[i][i] = 9999999999999;
Try this for minimum number
var min = int.MinValue
For max number
var max = int.MaxValue
Edited
Refer Reference
Number.Max_Value
Number.Min_Value
UPDATED
If you see your code you have filled the ind[] from 0
for(j=0;j<friends_cnt;j++) {
ind[j] = 0;
}
and in your while condition you have set value of i from 1. So for the last element it may be throwing error

Categories

Resources