This question already has answers here:
How do I create dynamic variable names inside a loop?
(8 answers)
Closed 3 months ago.
I can't figure out how to use dynamic variable in JS.. I have a list of ticker, some balances associated, and I want to display each 'balance sticker' in my loop, dynamically.
But it seems like it's not using the append I add to the variable at all?
var ticker = [CURRENCY1,CURRENCY2,CURRENCY3];
var balancesCURRENCY1 = 20;
var balancesCURRENCY2 = 30;
var balancesCURRENCY3 = 40;
for (var tick in ticker) {
if (('balances'+ticker[tick]) != 0) {
console.log(true);
}
}
To use dynmamic variables, keep the variableNames in an Object, whenever you create the variable name dynamically, refer the object to get the variable's value.
var ticker = ['CURRENCY1','CURRENCY2','CURRENCY3'];
var allBalances = {
balancesCURRENCY1 : 20,
balancesCURRENCY2 : 30,
balancesCURRENCY3 : 40
}
for (var tick in ticker) {
if (allBalances['balances'+ticker[tick]] != 0) {
console.log(true);
}
}
First of all you have to quote names in the array: [CURRENCY1,CURRENCY2,CURRENCY3], otherwise they would be handled as variables.
Then you can access your dynamic names from this see the snippet below:
var ticker = ['CURRENCY1', 'CURRENCY2', 'CURRENCY3'];
var balancesCURRENCY1 = 20;
var balancesCURRENCY2 = 30;
var balancesCURRENCY3 = 40;
for (var tick in ticker) {
if (this['balances'+ticker[tick]] != 0) {
console.log(
ticker[tick],
'balances'+ticker[tick] + ' = ' + this['balances'+ticker[tick]],
true
);
}
}
It would be cleaner to maintain 2 parallel arrays
var ticker = ['CURRENCY1','CURRENCY2','CURRENCY3'];
var balances = [20, 30, 40];
or an array of objects:
var tickerInfo = [
{currency: 'CURRENCY1', balance: 20},
{currency: 'CURRENCY2', balance: 30},
{currency: 'CURRENCY3', balance: 40},
];
Related
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.
I want to push objects into array (mainArr) in JS. Below is my code:
var object = {1: 15, 2: 30};
var mainArr = ['settingsData'];
var values = Object.values(object);
var final = [];
var counter = 0;
var portion = {};
for (var key in object) {
if (counter !== 0 && counter % 1 === 0) {
final.push(portion);
mainArr.push(portion)
portion = {};
}
portion[key] = values[counter];
counter++
}
final.push(portion);
mainArr.push(portion)
console.log(mainArr)
I see the output in the console like: ["settingsData", {1: 15}, {2: 30}]
But I want the output like:
{ "settingsData":[{"1":"4"},{"2":"3"}] }
You could map single key/value pairs as new entry.
var object = { 1: 15, 2: 30 },
settingData = Object.entries(object).map(keyValue => Object.fromEntries([keyValue])),
result = { settingData };
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Answer has already been accepted, but OP did request i put my comment as an answer.
This simplifies your approach drastically:
// Create a new object to start with:
let main = {"settingsData": []};
// Then push to the inner array:
main.settingsData.push({1:15});
If I understood it correctly, this would work:
var object = {1: 15, 2: 30};
var mainArr = {'settingsData': []};
var values = Object.values(object);
var final = [];
var counter = 0;
var portion = {};
for (var key in object) {
if (counter !== 0 && counter % 1 === 0) {
final.push(portion);
mainArr.push(portion)
portion = {};
}
portion[key] = values[counter];
counter++
}
final.push(portion);
mainArr.settingsData.push(portion)
console.log(mainArr)
EDIT: (Explanaition added as asked in comments)
What you were doing is push each element into the already existing array containing ['settingsData']. But what you were doing was to add items to the array located in the key settingsData.
So the changes were to set mainArr as an object containing field settingsData with an empty array as value, this is done on const mainArr = { settingData: []}
Then the push was done over the array contained in settingsData with mainArr.settingsData.push(newValue).
If you need further explanaition just ask.
I am facing an issue when populating an array of the object dynamically in javascript. I have this sample data as below:
I have to populate following arrays with the data from above:
c1_Arr = [];
c2_Arr = [];
var torontoObj = { arName: 'تورونتو', enName: 'Totonto', value: 0 };
var parisObj = { arName: 'باريس', enName: 'Paris', value: 0 };
var londonObj = { arName: 'لندن', enName: 'London', value: 0 };
Now I am looping through the data to set the values from data as:
var resultCount = results.features.length;
for (var i = 0; i < resultCount; i++) {
var data = results.features[i].attributes;
parisObj.value = data.Paris;
londonObj.value = data.London;
torontoObj.value = data.Toronto;
if (data.Ind_ID === 101) {
c1_Arr.push(parisObj);
c1_Arr.push(londonObj);
c1_Arr.push(torontoObj);
}
}
console.log(c1_Arr);
I am getting this data in console:
Here I am getting the values of the object i.e. Ind_ID = 102 instead of the object values of Ind_ID = 101 (first object).
How to get the values of the required object using the Ind_ID?
The problem is because even though you have the if condition there but you are updating the value of the objects in the loop and since you have already pushed them objects you still have the reference in the main objects. They get overwritten.
Create the 3 objects (torontoObj, etc.) inside the loop.
Reference is getting updated in the second iteration (where Ind_ID is 102)
You should rather do
var resultCount = results.features.length;
for (var i = 0; i < resultCount; i++) {
var data = results.features[i].attributes;
if (data.Ind_ID === 101) {
parisObj.value = data.Paris;
londonObj.value = data.London;
torontoObj.value = data.Toronto;
c1_Arr.push(parisObj);
c1_Arr.push(londonObj);
c1_Arr.push(torontoObj);
}
}
console.log(c1_Arr);
Your object values are getting updated even after being set inside the if loop, simply because, you're not limiting it from being updated.
You could probably do one of the following 2 things:
The simpler one:
Extract the values of Paris, London and Toronto fields of data only if the Ind
_ID is 101.
like this:
var resultCount = results.features.length;
for (var i = 0; i < resultCount; i++) {
var data = results.features[i].attributes;
if (data.Ind_ID === 101) {
parisObj.value = data.Paris;
londonObj.value = data.London;
torontoObj.value = data.Toronto;
c1_Arr.push(parisObj);
c1_Arr.push(londonObj);
c1_Arr.push(torontoObj);
}
}
console.log(c1_Arr);
The more elegant one:
Extract the array element which only matches your condition, in other words filter.
var resultCount = results.features.length;
var data = results.features.filter(feature => feature.attributes.Ind_ID === 101);
parisObj.value = data[0].Paris;
londonObj.value = data[0].London;
torontoObj.value = data[0].Toronto;
console.log(c1_Arr);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I know the pattern that basically tells you to create a js object and then pass in that object as a param into the parent function, but I have a slight twist on this that I wanted to see if was possible.
Say I have the following parent function
//helper functions
function handleArray(array, target, n) {
for (var i = 0; i < n; i++) {
array.push(new target());
}
}
//parent function
function tally(n1, n2, n3, n4, n5, cargo) {
var sportArray = [];
var familyArray = [];
var truckArray = [];
var miniArray = [];
var cargoArray = [];
var output =[];
var parsed = [];
var names = [];
//buids out my objects based on helper function above
handleArray(sportArray,SportsCar, n1);
handleArray(familyArray,FamilyCar, n2);
handleArray(truckArray,Truck, n3);
handleArray(miniArray,MiniVan, n4);
handleArray(cargoArray,CargoVan, n5);
//storing all the cars together in mega array
var carArray = sportArray.concat(familyArray, truckArray, miniArray, cargoArray);
//gives us a mapped array of just the capacity values stored in one neat array
var carsMapped = carArray.map( function(o) { return o.capacity; });
var startCargo = cargo; //maintain original in memory
var sumTotal = carsMapped.reduce(function(prev,curr){
return prev + curr;
});
// strggling hard core here maybe revise OO properties to make easier?
// var test = full(carsMapped, cargo);
// console.log();
//now for the printing finale!!!!
console.log("Allocating " + startCargo + " LB of cargo in total");
for(var i = 0; i < carArray.length; i++) {
names.push(carArray[i].type);
parsed.push(carArray[i].capacity);
console.log( "A " + names[i] + " with " + parsed[i] + " LBs");
}
console.log("We have " + cargo + " LBs of cargo left over.")
}
// //test output
tally(1,3,4,2,1, 7356);
// tally(1, 6, 1, 2, 3, 7356);
// // tally(1,1,1,1,1);
// // tally(0,0,1,0,0);
I want to be able to condense n1..n5 arguments into ideally just two arguments. However if I understand the options object param it would be something like this:
var options = {
sport: 'n1',
family: 'n2',
truck: n3,
mini: n4,
cargo: n5
}
function tally(options, cargo){...;}
This is fine except I cant actuallly set the values of n1..n5 like before hand and this is critical to my parent function tally to work because n1..n5 represent different objects that are created on the fly.
Any patterns or tips on how I could use less arguments while working around these issues?
Thanks~
Firstly, you had the order of the object's values backwards. It should be key: value, not the other way around. You use an object as the parameter when you call the method, but it doesn't have to be create beforehand, it can be done in the parameters like this.
tally ({n1: 'sport', n2: 'family', n3: 'truck', n4: 'mini', n5: 'cargo'});
Or, if you prefer making an object beforehand:
var options = {
n1: 'sport',
n2: 'family',
n3: 'truck',
n4: 'mini',
n5: 'cargo'
}
tally (options);
Where the function would be written as follows:
You can easily access the object's values by doing object.key (where the keys are, in this case, n1-n5, and the object is data).
function tally (data) {
var n1 = data.n1; //in this example, n1 = 'sport'
var n2 = data.n2; //and n2 = 'family'
//...
//Do stuff
}
If you wanted the first parameter value to be 4, you could do:
tally ({n1: 4, ...})
and if you wanted 10, you could do:
tally ({n1: 10, ...})
or if you just wanted it to match a previous variable x, you could do:
tally ({n1: x, ...})
EDIT: From your edited question code, you would do the following (only showing changed code for readability):
function tally(data, cargo) {
var sportArray = [];
var familyArray = [];
var truckArray = [];
var miniArray = [];
var cargoArray = [];
var output =[];
var parsed = [];
var names = [];
handleArray(sportArray,SportsCar, data.n1);
handleArray(familyArray,FamilyCar, data.n2);
handleArray(truckArray,Truck, data.n3);
handleArray(miniArray,MiniVan, data.n4);
handleArray(cargoArray,CargoVan, data.n5);
//Unchanged code removed
//test output
tally({n1: 1, n2: 3, n3: 4, n4: 2, n5: 1}, 7356);
tally({n1: 1, n2: 6, n3: 1, n4: 2, n5: 3}, 7356);
tally({n1: 1, n2: 1, n3: 1, n4: 1, n5: 1}, 1);
tally({n1: 0, n2: 0, n3: 1, n4: 0, n5: 0}, 0);
How about this type of solution:
function tally() {
var cargo = Array.prototype.pop.call(arguments);
if (arguments.length == 2) {
var options = arguments[0];
} else {
var options = {
sport: arguments[0],
...
}
}
}
This question already has answers here:
How to count duplicate value in an array in javascript
(35 answers)
Closed 7 years ago.
I have this JavaScript array with length 129.
var fullnames = [Karri, Ismo, Grigori, Ahmed, Roope, Arto .....]
I would like to find how many times those names appeared in an array and store that information in an array like this:
var counter = [2, 5, 7, ..]
where Karri occured in fullnames array 2 times, Ismo occured 5 times etc. Any ideas about how to do it?
This is the best - and simple - way I can think of:
var fullnames = ["Karri", "Ismo", "Grigori", "Ahmed", "Roope", "Ahmed", "Karri", "Arto", "Ahmed"];
var counts = {};
for (var i = 0; i < fullnames.length; i++)
{
if (!counts.hasOwnProperty(fullnames[i]))
{
counts[fullnames[i]] = 1;
}
else
{
counts[fullnames[i]]++;
}
}
console.log(counts);
Original Fiddle.
Using an array to store the counts doesn't makes much sense, so I used an object instead.
I am assuming that fullnames is array of strings. If so, you can do it like so:
var occurences = { };
for (var i = 0; i < fullnames.length; i++) {
if (typeof occurences[fullnames[i]] == "undefined") {
occurences[fullnames[i]] = 1;
} else {
occurences[fullnames[i]]++;
}
}
console.log(occurences); // Prints out something like: {"Karri": 2, "Ismo": 5, ...}
var fullnames = ['Karri', 'Ismo', 'Grigori', 'Karri', 'Ismo', 'Grigori', 'Grigori', 'Karri', 'Ismo', 'Grigori', 'Grigori'];
var counts = [];
fullnames.forEach(function(_item) {
if(typeof counts[_item] === 'undefined') counts[_item] = 1;
else counts[_item]++;
});
var result = [];
for(i in counts) result.push(counts[i]);
console.log(result);
// outputs [3, 3, 5]