Several JavaScript Objects are absolutely identical - javascript

steps["main_algorithm"] is filled with objects of the main_algorithm_structure.
main_algorithm_structure["loop1"] is filled with objects of the loop1_struct.
(The struct or structure objects are always copied with Object.create() or Object.assign({}, 'structure_name'))
The Problem is different objects of main_algorithm_structure, that means at the end different objects of steps["main_algorithm"] have the exact same loop1 object. I am trying to solve that problem for days now.. i am very desperate and this bug needs to be fixed...
Look at the Java Script Logic below those objects.
let steps = {
"str_to_hash" : "",
"init_constants" : [],
"input_to_bit_translation" : [],
"input_length_preprocessing" : [],
"final_input_preprocessing" : [],
"final_input_preprocessing_result" : [],
"main_algorithm" : [],
"hash_digest" : "",
}
let main_algorithm_structure = {
chunk_number : undefined,
chunk_preprocessed : undefined,
loop1 : [],
preConstants : undefined,
loop2 : [],
old_constants : undefined,
new_constants : undefined
}
let loop1_struct = {
lp1_sh1 : undefined,
lp1_sh2 : undefined,
lp1_add1 : undefined,
lp1_add2 : undefined,
lp1_s0 : undefined,
lp1_s1 : undefined,
lp1_y : undefined,
lp1_w : []
}
In the last if(crSteps) - Block, a copy of the loop1_structure is filled with data. This loop1_structure is pushed to main_algorithm_structure["loop1"]. Later in the algorithm this main_algorithm structure is further filled with data and at the end pushed to steps["main_algorithm"]. At the end of the whole script, the structure steps is returned by the function.
In every object of steps["main_algorithm"] the loop1-array is exactly the same. Why?
I hope the for-loop is everything which is needed to find the bug:
for(let x = 0; x<chunks.length; x++) {
if(crSteps) {structCopy = Object.assign({}, main_algorithm_structure)}
if(crSteps) {structCopy.chunk_number = x}
//chunking every 512 bit chunk into 32 bit chunks -> w's result is 16 32 bit chunks
let w = chunker(chunks[x], 32)
//adding 48 32 bit chunks (every chunk is full of zeros)
for(let m = 0; m != 48; m++) {
w.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
if(crSteps) {
let toPush = []
for(let c = 0; c<w.length; c++) {
let temp = ""
for(let c_ = 0; c_<w[c].length; c_++) {
temp += String(w[c][c_])
}
toPush.push(temp)
}
structCopy["chunk_preprocessed"] = toPush.slice()
}
for(let y = 16; y<64; y++) {
const sh1 = y-15
const sh2 = y-2
const add1 = y-16
const add2 = y-7
const s0 = XORXOR(rotr(w[sh1].slice(), 7), rotr(w[sh1].slice(), 18), shr(w[sh1].slice(), 3))
const s1 = XORXOR(rotr(w[sh2].slice(), 17), rotr(w[sh2].slice(), 19), shr(w[sh2].slice(), 10))
w[y] = add(add(add(w[add1].slice(), s0), w[add2].slice()), s1)
if(crSteps) {
let copy_loop1_struct = Object.create(loop1_struct)
copy_loop1_struct.lp1_sh1 = sh1
copy_loop1_struct.lp1_sh2 = sh2
copy_loop1_struct.lp1_add1 = add1
copy_loop1_struct.lp1_add2 = add2
copy_loop1_struct.lp1_s0 = s0.slice()
copy_loop1_struct.lp1_s1 = s1.slice()
copy_loop1_struct.lp1_y = y
let toPush= []
for(let c = 0; c<w.length; c++) {
toPush.push(w[c].slice().join(""))
}
copy_loop1_struct.lp1_w = toPush.slice()
structCopy.loop1.push(copy_loop1_struct)
}
}

Related

Algorithm - River Sizes - Code works but prompt complains memory leak

Can people help to point out the problem with the code below? By inspecting the console.log, the code is working as intended, however, the prompt complains "Oops, your code timed out or ran out of memory. Check for infinite loops or memory leaks."
The code is not stuck in an infinite loop, so it must be about memory leaks. What is a memory leak, what is the problems with the code? Appreciated!
function riverSizes(matrix) {
let isVisitedMatrix = Array(matrix.length).fill(false).map(ele => Array(matrix[0].length).fill(false));
let lengthMatrix = [];
for (let row=0; row<matrix.length; row++)
{
for (let col=0; col<matrix[0].length; col++)
{
if (isVisitedMatrix[row][col] === true) continue;
isVisitedMatrix[row][col] = true;
if (matrix[row][col]===1)
{
const startNode = new Node(row, col);
const length = traverseNeighbour(matrix, [startNode], 1, isVisitedMatrix);
lengthMatrix.push(length);
}
}
}
return lengthMatrix; }
function traverseNeighbour(matrix, queue, currLength, isVisitedMatrix)
{
if (queue.length === 0) return currLength;
const startNode = queue.shift();
const row = startNode.row;
const col = startNode.col;
isVisitedMatrix[row][col] = true;
if (row-1>=0 && matrix[row-1][col]===1 && isVisitedMatrix[row-1][col]===false)
{
currLength += 1;
const top = new Node(row-1, col);
queue.push(top);
}
if (row+1<matrix.length && matrix[row+1][col]===1 && isVisitedMatrix[row+1][col]===false)
{
currLength += 1;
const bottom = new Node(row+1, col);
queue.push(bottom);
}
if (col-1>=0 && matrix[row][col-1]===1 && isVisitedMatrix[row][col-1]===false)
{
currLength += 1;
const left = new Node(row, col-1);
queue.push(left);
}
if (col+1 < matrix[0].length && matrix[row][col+1]===1 && isVisitedMatrix[row][col+1]===false)
{
currLength += 1;
const right = new Node(row, col+1);
queue.push(right);
}
return traverseNeighbour(matrix, queue, currLength, isVisitedMatrix);
}
class Node {
constructor(_row, _col)
{
this.row = _row;
this.col = _col;
}
}
Here is the question.
You're given a two-dimensional array (a matrix) of potentially unequal height and width containing only 0s and 1s. Each 0 represents land, and each 1 represents part of a river. A river consists of any number of 1s that
are either horizontally or vertically adjacent (but not diagonally adjacent). The number of adjacent 1 s forming a river determine its size.
Note that a river can twist. In other words, it doesn't have to be a straight vertical line or a straight horizontal line; it can be L-shaped, for example.
Write a function that returns an array of the sizes of all rivers represented in the input matrix. The sizes don't need
to be in any particular order.
Sample Input
matrix = [
[1, 0, 0, 1, 0],
[1, 0, 1, 0, 0],
[0, 0, 1, 0 ,1],
[1, 0, 1, 0, 1],
[1, 0, 1, 1, 0],
]
Sample Output
[1, 2, 2, 2, 5] // The numbers could be ordered differently.
// The rivers can be clearly seen here:
// [
// [1, , , 1, ],
// [1, , 1, , ],
// [, , 1, , 1],
// [1, , 1, , 1],
// [1, , 1, 1, ],
// ]
Try marking the visited right before adding the node to the queue so that you can ensure that you only add a node to the queue once. Right now, you mark the nodes once they dequeue, so your queue is probably getting extremely big.
By the way, this whole "traverse a 2d array" stuff comes up a lot, so it's best to just memorize a simple dfs implementation like this:
const getRiverCount = map => {
const sizes = [];
const h = map.length;
const w = map[0].length
const dfs = (r, c) => {
if (r < 0 || c < 0 || r >= h || c >= w || map[r][c] === 0) return 0;
map[r][c] = 0;
return dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1) + 1;
}
for (let r = 0; r < h; r++) {
for (let c = 0; c < w; c++) {
if (map[r][c] === 1) sizes.push(dfs(r, c));
}
}
return sizes;
}
Actually, the code isn't error-free (previously it repetitively adds nodes already in the queue to the queue again if that node is also neighbour with new nodes). After I edited the code, it passed all the tests :)
function riverSizes(matrix) {
const isVisitedMatrix = Array(matrix.length).fill(false).map(ele => Array(matrix[0].length).fill(false));
let lengthMatrix = [];
for (let row=0; row<matrix.length; row++)
{
for (let col=0; col<matrix[0].length; col++)
{
if (isVisitedMatrix[row][col] === true) continue;
isVisitedMatrix[row][col] = true;
if (matrix[row][col]===1)
{
const startNode = new Node(row, col);
const length = traverseNeighbour(matrix, [startNode], 0, isVisitedMatrix);
lengthMatrix.push(length);
}
}
}
return lengthMatrix;}
function traverseNeighbour(matrix, queue, currLength, isVisitedMatrix)
{
if (queue.length === 0) return currLength;
const startNode = queue.shift();
currLength += 1;
const row = startNode.row;
const col = startNode.col;
isVisitedMatrix[row][col] = true;
if (row-1>=0 && matrix[row-1][col]===1 && isVisitedMatrix[row-1][col]===false)
{
const top = new Node(row-1, col);
isVisitedMatrix[row-1][col] = true;
queue.push(top);
}
if (row+1<matrix.length && matrix[row+1][col]===1 && isVisitedMatrix[row+1][col]===false)
{
const bottom = new Node(row+1, col);
isVisitedMatrix[row+1][col] = true;
queue.push(bottom);
}
if (col-1>=0 && matrix[row][col-1]===1 && isVisitedMatrix[row][col-1]===false)
{
const left = new Node(row, col-1);
isVisitedMatrix[row][col-1] = true;
queue.push(left);
}
if (col+1 < matrix[0].length && matrix[row][col+1]===1 && isVisitedMatrix[row][col+1]===false)
{
const right = new Node(row, col+1);
isVisitedMatrix[row][col+1] = true;
queue.push(right);
}
return traverseNeighbour(matrix, queue, currLength, isVisitedMatrix);}
class Node {
constructor(_row, _col)
{
this.row = _row;
this.col = _col;
}
}

How to change value of element in array in for loop

I have the following array :
for (let i of lastBal) {
var amtToDetect = received_amt;
console.log('amt to detect', amtToDetect);
var lpcForLoop = i.lpc;
var lic_fee_for_loop = i.lic_fee;
var daysDifference_for_loop = i.lpdays;
var onlineLPC_for_loop = i.onlinelpc;
var total_amt_for_loop = i.total_amt;
console.log('lic fee for loop', i.lic_fee);
if (amtToDetect >= lic_fee_for_loop) {
var remainAmtAfterLPC = Math.floor(amtToDetect - lpcForLoop);
var paidLPC = amtToDetect - remainAmtAfterLPC;
if (remainAmtAfterLPC > 0) {
if (remainAmtAfterLPC >= lic_fee_for_loop) {
var remainBalanceAfterLicFee = remainAmtAfterLPC - lic_fee_for_loop
var paidLicFee = remainAmtAfterLPC - remainBalanceAfterLicFee;
var total_amt_payment = Math.floor(paidLicFee + lpcForLoop);
//for balance entry
var bal_lic_fee = Math.floor(lic_fee_for_loop - paidLicFee);
var bal_LPC = Math.floor(lpcForLoop - lpcForLoop);
var bal_total_amt = Math.floor(bal_lic_fee + bal_LPC);
}
}
}
//console.log('demand in for loop',demandInsertData);
let difference = paymentDate - lic_fee_due_date;
var daysDifference = Math.floor(difference / 1000 / 60 / 60 / 24);
var onlineLPC = Math.floor(lic_fee * 0.18 * daysDifference / 365);
var currentLPC = Math.floor(onlineLPC + bal_LPC);
var total_amt = Math.floor(lic_fee + currentLPC);
console.log('in end for loop');
i.lpc = onlineLPC;
i.lic_fee = lic_fee - i.lic_fee;
console.log('in end for loop lic fee', i.lic_fee);
i.lpdays = daysDifference;
i.total_amt = total_amt;
received_amt = remainBalanceAfterLicFee;
console.log('in end for loop received_amt', received_amt);
}
In the above for loop, I want to replace some elements from lastBal array.
At the end of the for loop, I tried to replace some elements as follows :
i.lic_fee = lic_fee - i.lic_fee;
However, values are not being replaced during the next iteration. Instead, old values are being assigned.
How can I find the issue here?
Edit
After changing elements values I want to use them in same for loop.
Means after 1st iteration in for loop I want to change the values of element and use the updated values in next iteration.
Here at end of loop values are updated, but in second iteration old values form lastBal are assign.
Edit 2: Added lastBal
last bal [ RowDataPacket {
demand_id: 42,
user_id: 4,
lic_id: 4,
description: 'Balance',
demand_start_date: '2020-07-01',
demand_end_date: '2020-09-30',
demand_fin_year: '2020-2021',
lic_fee: 27000,
form_fee: 0,
lic_fee_due_date: '2020-06-30',
lrc: 0,
srtax: 0,
lpc: 1224,
total_amt: 28224,
outstanding_amt: 28224,
lpdays: 92,
onlinelpc: 1224,
flag: 0,
lic_fee_pay_id: 0,
demand_added_date: '2020-04-28 19:43:14',
payment_date: '0000-00-00 00:00:00' },
RowDataPacket {
demand_id: 44,
user_id: 4,
lic_id: 4,
description: 'Balance',
demand_start_date: '2020-10-01',
demand_end_date: '2020-12-31',
demand_fin_year: '2020-2021',
lic_fee: 54000,
form_fee: 0,
lic_fee_due_date: '2020-09-30',
lrc: 0,
srtax: 0,
lpc: 1224,
total_amt: 55224,
outstanding_amt: 55224,
lpdays: 0,
onlinelpc: 0,
flag: 0,
lic_fee_pay_id: 0,
demand_added_date: '2020-04-28 19:52:25',
payment_date: '0000-00-00 00:00:00' } ]
Above array is fetch from database.I want to updated 2nd RowDataPacket after 1st iteration in for loop.values to updated 2nd RowDataPacket are dynamic.
Well, I did try to reproduce with your code while putting some sample values in the fields wherever necessay and I do see the expected modifications. Hence, you need to clarify where exactly you're not seeing the changes that you're expecting.
var lastBal = [{ lpc: 1, lic_fee: 2, lpdays: 9, onlinelpc: 4, total_amt: 2 }, { lpc: 3, lic_fee: 4, lpdays: 2, onlinelpc: 5, total_amt: 1 }];
var editedValues = {};
for (let i of lastBal) {
if (!(Object.keys(editedValues).length === 0 && editedValues.constructor === Object)) {
i = {...i, ...editedValues} ;
}
var amtToDetect = 5;
console.log('amt to detect', amtToDetect);
var lpcForLoop = i.lpc;
var lic_fee_for_loop = i.lic_fee;
var daysDifference_for_loop = i.lpdays;
var onlineLPC_for_loop = i.onlinelpc;
var total_amt_for_loop = i.total_amt;
console.log('lic fee for loop', i.lic_fee);
if (amtToDetect >= lic_fee_for_loop) {
var remainAmtAfterLPC = Math.floor(amtToDetect - lpcForLoop);
var paidLPC = amtToDetect - remainAmtAfterLPC;
if (remainAmtAfterLPC > 0) {
if (remainAmtAfterLPC >= lic_fee_for_loop) {
var remainBalanceAfterLicFee = remainAmtAfterLPC - lic_fee_for_loop
var paidLicFee = remainAmtAfterLPC - remainBalanceAfterLicFee;
var total_amt_payment = Math.floor(paidLicFee + lpcForLoop);
//for balance entry
var bal_lic_fee = Math.floor(lic_fee_for_loop - paidLicFee);
var bal_LPC = Math.floor(lpcForLoop - lpcForLoop);
var bal_total_amt = Math.floor(bal_lic_fee + bal_LPC);
}
}
}
//console.log('demand in for loop',demandInsertData);
var daysDifference = 5000;
var onlineLPC = 2000;
var currentLPC = 1000;
var total_amt = 1500;
console.log('in end for loop');
i.lpc = onlineLPC;
i.lic_fee = 4000 - i.lic_fee;
console.log('in end for loop lic fee', i.lic_fee);
i.lpdays = daysDifference;
i.total_amt = 7000;
received_amt = 11000;
console.log('in end for loop received_amt', received_amt);
editedValues = {
pc: onlineLPC,
lic_fee: lic_fee - i.lic_fee,
lpdays: daysDifference,
total_amt: total_amt,
onlinelpc: onlineLPC,
received_amt: remainBalanceAfterLicFee
} // Whatever values you'd like to retain for the subsequent execution
}
console.log(lastBal);
EDIT
- Updated accordingly as you updated your requirements.
Because you are not accessing the array index/key, or in this case the object in javascript.
Take a look at the code below, I can't change "b to bb" assigning "bb" to the variable display the value in the for loop (key). In this case key='bb' will print the value but it will not change it.
var test = [];
test = ['a','b','c','d','e','f','g','h','i'];
for (let key of test){
if (key == 'b') { key = 'bb'}
console.log(key);
}
test[1] = 'cc';
for (let key of test){
console.log(key);
}
In order to change the value in the object/array you need to reference the index/key from the original array. test[1]='cc'; then the value will be changed.
Run the code commenting the test[1]='cc'; line, you will see that the value was not change in the initial loop, then run it uncommenting the line.

How to "update" a variable?

I have this:
let points = something
let obj1 = {
points: points
}
The points value changes
let obj2 = {
points: points
}
I want that obj1.points is equal to the first points value and obj2.points the second. Here's more of the code:
constructor($){
let stats = $(".player-stats-info").get(0);
let points = parseInt(stats.children[5]) || 0;
this.rush = {
points: points
}
stats = $(".player-stats-info").get(1);
this.hikaBrain = {
points: points
}
stats = $(".player-stats-info").get(2);
this.skyWars = {
points: points
}
stats = $(".player-stats-info").get(3);
this.octogone = {
points: points
}
//etc
}
It sounds like you want a function that returns an object with the right structure:
const makeObj = stats => ({
points: parseInt(Object.byString(stats.children[5], d)) || 0,
gameCount: parseInt(Object.byString(stats.children[7], d)) || 0,
victoryCount: parseInt(Object.byString(stats.children[9], d)) || 0,
defeatCount: parseInt(Object.byString(stats.children[11], d)) || 0,
gameTime: ms(Object.byString(stats.children[13], d)) || 0,
killCount: parseInt(Object.byString(stats.children[15], d)) || 0,
deathCount: parseInt(Object.byString(stats.children[17], d)) || 0,
});
Then just call makeObj with the stats:
this.rush = makeObj($(".player-stats-info").get(0));
this.skyWars = makeObj($(".player-stats-info").get(1));
// etc

Javascript convert array with null value to string

I have the array
localCostp:
0:null
1:null
2:0.5
3:null
4:null
5:null
6:0.5
7:null
8:null
and i would like to convert it in a string like the below
"[],[],[0.5],[],[],[],[0.5],[],[]"
i have tried the below
console.log("[" + Object.values(localCostp).join("],[") + "]");
but i lose the null value
"[0.5],[0.5]"
i fill the array with the below code
Array.prototype.shuffle = function() {
var r=[],c = this.slice(0);
for (let i = c.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[c[i], c[j]] = [c[j], c[i]];
}
return c;
};
Array.prototype.populateUnique = function(n) {
return Object.keys( Object( 0+Array(n) ) );
};
var getRandomInts = function(num, min, max) {
var a = [].populateUnique(max+1).slice(min);
a = a.shuffle();
return a.slice(0,num);
};
BordsIdtoFill = getRandomInts(NumOfBoardToFill,1,6);
switch(retrivePanelsPanelsbetType(configGenerateData.panelsBetType)) {
case 1: case 2:{
gameMultiplayer = 1;
} break;
case 3: case 4 : case 5: {
gameMultiplayer = 2;
} break;
case 6: {
gameMultiplayer = 2;
} break;
}
var localCostp = new Array(9);
BordsIdtoFill.forEach(function(Bord) {
localCostp[Bord]= (1*gameMultiplayer * 0.5)
});
console.log("[" + Object.values(localCostp).join("],[") + "]");
not all the array position are filled
The naive way of doing would be to
const arr = [null, null, 0.5, null, 0.5]
const processedArr = arr.map(element => {
if (element) {
return [element];
} else {
return [];
}
});
const result = JSON.stringify(processedArr);
console.log(result)
A shorter, but less readable way of doing it will be to use the following:
const arr = [null, null, 0.5, null, 0.5];
const result = `[[${arr.join('],[')}]]`;
console.log(result);
That's interesting output. :-)
In a comment you've said:
i fill the array with the below code
var localCostp = new Array(9);
BordsIdtoFill.forEach(function(Bord) {
localCostp[Bord] = (1*gameMultiplayer * 0.5);
});
not all the array position are filled
That's very different from the array you showed. The array you showed had nulls in it. That array has gaps in it. When you read the value of a gap, you get back undefined (not null).
To do it, you'll either want to use a simple for loop, a for-of loop or something other way of using the iterable from values (which includes gaps), or fill the gaps first.
For instance, this uses the iterable from values:
const string = [...localCostp.values()].map(entry => JSON.stringify(entry === undefined ? [] : [entry])).join();
Live Example:
const localCostp = new Array(9);
localCostp[2] = 0.5;
localCostp[6] = 0.5;
const string = [...localCostp.values()].map(entry => JSON.stringify(entry === undefined ? [] : [entry])).join();
console.log(string);
In another comment you've said:
if i run your code on my enviroment i take There was an error in evaluating the Pre-request Script: TypeError: localCostp.values(...)[Symbol.iterator] is not a function
That's surprising, values was added in ES2015, the same time Symbol.iterator and array spread were, but your error message makes it seem like you have the latter but not the former. I suspect you're transpiling and missing a polyfill.
Here's an ES5 version (can't use map because it won't visit the gaps):
var result = [];
for (var i = 0; i < localCostp.length; ++i) {
var entry = localCostp[i];
result[i] = JSON.stringify(entry === undefined ? [] : [entry]);
}
result = result.join();
Live Example:
var localCostp = new Array(9);
localCostp[2] = 0.5;
localCostp[6] = 0.5;
var result = [];
for (var i = 0; i < localCostp.length; ++i) {
var entry = localCostp[i];
result[i] = JSON.stringify(entry === undefined ? [] : [entry]);
}
result = result.join();
console.log(result);
You can just use Array#map to produce either [] for null value or enclose the number in square brackets, then Array#join to get the desired output:
let arr = [
null,
null,
0.5,
null,
null,
null,
0.5,
null,
null
]
let str = arr
.map(item => item === null ? "[]" : `[${item}]`)
.join();
console.log(str);
You could map the values in an array or not and stringify the data and get the string between the outer brackets.
var data = [null, null, 0.5, null, null, null, 0.5, null, null],
result = JSON.stringify(data.map(v => v === null ? [] : [v])).slice(1, -1);
console.log(result);
An example with template strings.
var data = [null, null, 0.5, null, null, null, 0.5, null, null],
result = data.map(v => `[${v === null ? '' : v}]`).join();
console.log(result);
With an array with sparse items.
var array = [, , 0.5, , , , 0.5, , ],
result = Array.from(array, (v = '') => `[${v}]`).join();
console.log(result);

constructor within a constructor in javascript?

I want a constructor within a constructor- I've searched stackoverflow and googled extensively......
I have a constructor RentalProperty:
function RentalProperty(numberOfUnits, address, dateAcquired, acCost, isFinanced,
loanAmount){
this.numberOfUnits = numberOfUnits;
this.address = address;
this.dateAcquired = new Date(dateAcquired);
this.acCost = acCost;
this.isFinanced = isFinanced;
this.loanAmount = 0;
this.newValue = 0;
this.equity = function(){
if (this.newValue === 0){
return (this.acCost - this.loanAmount);
} else {
return (this.newValue - this.loanAmount);
}
};
}
Each instance of RentalProperty will have a series of unit objects that I would like to be unit1, unit2, unit3, etc. However some instances of RentalProperty will have only one unit while others may have six, twelve, or more. The way I'm doing it here doesn't seem right as there is a lot of repetition of code and I will need to make a large number of unit objects that may not be used for a particular instance of RentalProperty:
RentalProperty.prototype.unit1 = {
unitNumber : "1",
monthlyRent: 0,
leaseStart: new Date(0),
leaseEnd: new Date(0),
numBeds: 0,
isSec8: false,
tenantPortion: 0,
sec8Portion: 0
};
RentalProperty.prototype.unit2 = {
unitNumber : "2",
monthlyRent: 0,
leaseStart: new Date(0),
leaseEnd: new Date(0),
numBeds: 0,
isSec8: false,
tenantPortion: 0,
sec8Portion: 0
};
RentalProperty.prototype.unit3 = {
unitNumber : "3",
monthlyRent: 0,
leaseStart: new Date(0),
leaseEnd: new Date(0),
numBeds: 0,
isSec8: false,
tenantPortion: 0,
sec8Portion: 0
};
I tried various combinations of syntax (I've been pulling my hair out for hours) to put a unit constructor within the RentalProperty constructor with code such as:
....
this.unit["for(i=0, i < this.numberOfUnits, i++){return i;}"] = {
unitNumber : "i",
monthlyRent: 0,
leaseStart: new Date(0),
leaseEnd: new Date(0),
numBeds: 0,
isSec8: false,
tenantPortion: 0,
sec8Portion: 0
};
....hoping that this would create the correct number of units using the value of the this.numOfUnits property of RentalProperty but it gives me "missing operand".
I have also tried:
....//'new Object' added
this.unit[for(i=0, i < this.numberOfUnits, i++){return i;}] = new Object{
unitNumber : "i",
monthlyRent: 0,
leaseStart: new Date(0),
leaseEnd: new Date(0),
numBeds: 0,
isSec8: false,
tenantPortion: 0,
sec8Portion: 0
};
....
....//trying to make another constructor
function Units(){
unitNumber = "1";
monthlyRent = 0;
leaseStart = new Date(0);
leaseEnd = new Date(0);
numBeds = 0;
isSec8 = false;
tenantPortion = 0;
sec8Portion = 0;
}
var yale = new RentalProperty()
var yale.unit33 = new Units();
....but when I try to make an instance of the new Units class with the RentalProperty instance before it in dot notation it says 'Unexpected Token'.
I have only been learning to code for 2 months (approx one month each of html and javascript) so I'm pretty sure this is a noob question. Any help would be much appreciated..... This is also my first stackoverflow question so please accept my apologies if my formatting is off.
It seems like you want
this.units = []; // an array which
for (var i=0; i < this.numberOfUnits; i++) { // in a loop
this.units[i] = { // is filled with objects
unitNumber : i,
monthlyRent: 0,
leaseStart: new Date(0),
leaseEnd: new Date(0),
numBeds: 0,
isSec8: false,
tenantPortion: 0,
sec8Portion: 0
};
}
Of course instead of the object literal you also can use new Units(i) or something to create the unit objects.
If you don't want an array, but make numbered properties on your object (I'd discourage from that) it would be
this["unit"+i] = …
You are overcomplicating things. As long as there is a Unit constructor already defined you can just do:
function RentalProperty(numberOfUnits){
this.numberOfUnits = numberOfUnits;
this.units = [];
for (var i = 0; i < numberOfUnits; ++i) {
this.units.push(new Unit(i));
}
}
This constructor can be globally scoped, as in
function Unit(unitNumber) {
this.unitNumber = unitNumber;
}
or you can also make it a property of RentalProperty:
RentalProperty.Unit = function(unitNumber) {
this.unitNumber = unitNumber;
}
in which case you would create units with new RentalProperty.Unit(i).
Just consider a completely independent constructor for Unit
RentalProperty.Unit = function Unit(i) {
if (undefined === i) i = 1;
this.unitNumber = '' + i;
this.monthlyRent = 0;
this.leaseStart = new Date(0);
this.leaseEnd = new Date(0);
this.numBeds = 0;
this.isSec8 = false;
this.tenantPortion = 0;
this.sec8Portion = 0;
};
I put it as a property of RentalProperty to keep everything neat.
Next generate all your units in your RentalProperty constructor, or however..
this.units = [];
var i;
for (i = 0; i < this.numberOfUnits; ++i) {
this.units.push(new RentalProperty.Unit(i));
}
Doing it this way also means you can set up a prototype chain for Unit, should you desire to, and you can confirm that a unit u is indeed a Unit using u instanceof RentalProperty.Unit.
The question has been answered several times but here is the full code.
function Unit(rentProp){
this.unitNumber = ""+(rentProp.units.length+1);
this.rentalProperty=rentProp
//all of the foolowing props could go on prototype
//because the constructor fills them only with default values
//later you'll assign new values to them with
//someUnitInstance.monthlyRent=...
this.monthlyRent = 0;
this.leaseStart = null;
this.leaseEnd = null;
this.numBeds = 0;
this.isSec8 = false;
this.tenantPortion = 0;
this.sec8Portion = 0;
}
function RentalProperty(numberOfUnits, address
, dateAcquired, acCost, isFinanced
,loanAmount){
this.numberOfUnits = numberOfUnits;
this.address = address;
this.dateAcquired = new Date(dateAcquired);
this.acCost = acCost;
this.isFinanced = isFinanced;
this.units=[];
};
//default values on prototype, assuming you're not using
//hasOwnProperty later to iterate through properties because
//defaults (on prototype) won't show up
RentalProperty.prototype.loanAmount = 0;
RentalProperty.prototype.newValue = 0;
RentalProperty.prototype.equity = function(){
if (this.newValue === 0){
return (this.acCost - this.loanAmount);
} else {
return (this.newValue - this.loanAmount);
}
};
RentalProperty.prototype.addUnit = function(){
this.units.push(new Unit(this));
}
var r=new RentalProperty();
r.addUnit();
r.addUnit();
console.log(r.units);

Categories

Resources