How to change Key of an object dynamically - javascript

I have an object like this:
var obj{};
I want to set object values dynamically like so:
for(i=0;i<10;i++)
{
quest='quest'+i;
header='header'+i;
$(obj).data(quest,{header:i});
quest,header=0;
}
I'm expecting object to be saved like:
obj{quest1:{header1:1},
quest2:{header2:2}
quest3:{header3:3}
But they are saved like:
obj{quest1:{header:1},
quest2:{header:2},
quest3:{header:3},
The header-key in my object is not getting the actual value. but simply save as "header"..
Could you please guide me here?

You can write:
var obj = {};
for(i=1; i<11; i++) {
quest='quest'+i;
header='header'+i;
obj[quest] = {};
obj[quest][header] = i;
}

In your code your loop starts with i = 0 but the properties start by 1.
var quest, header, obj = {};
for (i = 0; i < 10; i += 1) {
quest = 'quest' + (i + 1);
header = 'header' + (i + 1);
obj[quest] = {};
obj[quest][header] = (i + 1);
}

You cannot have a variable key in an object literal.

Related

Create variable name with increment

I need to create dynamically name of variable with a loop .
example:
const1 = test;
const2 = test;
const3 = test;
....
I try this , but that only create 20 same variable name in array
I need a unique name increment by 1 at each loop and return each variable to use after.
function createVariables(){
var accounts = [];
for (var i = 0; i <= 20; ++i) {
accounts[i] = "whatever";
}
return accounts;
}
how can I do this ?
Using Object could be the work around
var accounts = {};
for (var i = 0; i <= 20; ++i) {
accounts["const"+i] = "test";
}
console.log(accounts)
If you need variable (not array), then you can use this code:
for (let i = 0; i <= 20; ++i) {
window[`whatever${i}`] = + i;
}
console.log(whatever0)
console.log(whatever1)
//...
console.log(whatever19)
See in playground: https://jsfiddle.net/denisstukalov/thvc2ew8/4/
What is it that you are trying to achieve? As mentioned in some of the comments, and array would be a better approach.
That said, one solution is to set values on a JavaScript object using string indexer (['']). See example below:
function createVariables(obj){
for (var i = 0; i <= 20; ++i) {
obj[`const${i}`] = "whatever";
}
}
// add it to a new object
const accounts = {};
createVariables(accounts);
console.log(accounts.const1, accounts.const2, accounts.const3);
// avoid adding it to global scope (like window)
createVariables(window);
console.log(const1, const2, const3);

Can I concat a string and a variable to select a DOM element in JavaScript?

I have tried Googling this question but no luck. Probably because I'm asking the wrong way. Any help is much appreciated.
I have variables copy1, copy2, etc. I want to iterate through them and select each one to check if it's contents has a certain number of characters. When I use any variation of the below, it will either console an error or output a string in the console.
var copy1 = document.getElementById('copy1');
var copy2 = document.getElementById('copy2');
var copy3 = document.getElementById('copy3');
for(var i=0;i<4;i++){
console.log(copy+i);
console.log("copy"+i);
};
Ideally I would be able to select an element and style that via javascript.
Much appreciated
Thanks All.
Moe
Agree with #jaromanda-x:
var copy1 = document.getElementById('copy1');
var copy2 = document.getElementById('copy2');
var copy3 = document.getElementById('copy3');
for (var i=1; i<4; i++) {
console.log(window['copy'+i]);
};
Or you can use more simple example, like:
for (var i=1; i<4; i++) {
var name = 'copy' + i;
console.log(document.getElementById(name));
};
Or even:
for (var i=1; i<4; i++) {
console.log(document.getElementById('copy' + i));
};
You can store the properties in an object where values are set to the DOM element
let copies = {
1 : document.getElementById('copy1'),
2 : document.getElementById('copy2'),
3 : document.getElementById('copy3')
}
for (let [key, prop] of Object.entries(copies)) {
console.log(key, prop)
}
console.log(copies[1], copies[2], copies[3]);
Or use attribute begins with and attribute ends with selectors with .querySelector()
let n = 1;
let copy1 = document.querySelector(`[id^=copy][id$='${n}']`); // `#copy1`
let copy2 = document.querySelector(`[id^=copy][id$='${++n}']`); // `#copy2`
for (let i = 1; i < 4; i++) {
console.log(document.querySelector("[id^=copy][id$=" + i + "]"));
}
Since nobody has addressed your "certain number of characters" requirement yet, I thought I would.
You could always use jQuery or write your own $ method, which works as a document.getElementById() wrapper function.
Here is a jsfiddle to see it in action.
HTML
<div id="copy1">01234</div>
<div id="copy2">012345678</div>
<div id="copy3">0123456789 0123456789</div>
JavaScript
// Isn't this just a brilliant short-cut?
function $(id) {
return document.getElementById(id);
}
for (let i=1; i<4; i++){
let obj = $('copy' + i);
let value = (obj) ? obj.innerText : '';
console.log('value.length:', value.length);
};

How can I stringify output from a for loop?

I have the following for loop and I would like the output of the loop to be stringified into a query string as shown in the desired output below. I'm using the qs npm package for stringifying URLs.
What's the best way of going about getting the desired output?
for (i = 0; i < 2; i++) {
var foo = "pr" + [i] + "va";
var bar = "value";
};
//Desired output: ?pr0va=value&pr1va=value
Instead of creating variables - create String and do concatenation in every loop.
Check my code snippet.
var query = "";
var size = 2;
for (i = 0; i < size; i++) {
query += "pr" + [i] + "va=value";
if (i+1<size)
query += "&";
};
console.log(query);
This should work for you.
function test () {
var i =0;
var arr = [];
for(i=0;i<2;i++) {
arr.push( "pr" + [i] + "va=value" );
}
console.log('?' + arr.join('&').toString())
}
Something like this?
var output = '?';
for (i = 0; i < 2; i++) {
var foo = "pr" + [i] + "va";
var bar = "value";
output += foo + "=" + bar + "&";
};
console.log(output);
//Desired output: ?pr0va=value&pr1va=value
You can do it like this.
var output = "?";
for (i = 0; i < 2; i++) {
output += "pr" + [i] + "va=value&";
};
console.log(output.slice(0, -1))
If I were to review such code I would prefer to see the following:
Avoid concatenation.
Use of functional programming.
Reasonable usage of 3rd parties - so yes for querystring
All of those are for readability, simplicity and maintainability benefits. And I admit it is arguable.. so please don't argue :)
I will use your code as a baseline and improve from there
for (i = 0; i < 2; i++) {
var foo = "pr" + [i] + "va";
var bar = "value";
};
Note that your snippet is incomplete, and so, at the beginning mine will not be complete too, but I'll get there
Avoid concatenation
I will avoid concatenation using template literal
for (i = 0; i < 2; i++) {
`pr${i}va=value`;
};
Use of functional programming
I will iterate over numbers using an array, and reduce to construct an object
const queryParams = Array(2).fill().reduce((object, value, index) => {
object[`pr${index}va`] = 'value';
return object;
} , {} )
Using 3rd parties
Now I will use querystring to turn queryParams to a query string
return querystring.stringify(queryParams);
All together now
/**
* #param {number} count - number of query parameters to generate
* #returns {string} query string. for example for count=2 will return `pr1va=value&pr2va=value`
**/
function generateQueryString(count=2){
const queryParams = Array(count).fill().reduce((object, value, index) => { // convert N number to key-value map using reduce
object[`pr${index}va`] = 'value';
return object;
} , {} );
return querystring.stringify(queryParams);
}
You can create an array of size, loop and then join it:
function createString(size) {
return new Array(size).fill(0).map((v, i) => {
return "pr" + i + "va=value";
}).join("&");
}
console.log(createString(2));

get value from variable dynamically

I'm trying, but unsuccessfully, to get the value of a variable, where the variable name is dynamic
var v_1playerName = document.getElementById("id_1playerName").value;
var v_2playerName = document.getElementById("id_2playerName").value;
for (i = 1; i <=5 i++) {
alert(window["v_"+i+"playerName"]);
}
Is this possible?
A simple thing would be to put the variables in an array and then use the for loop to show them.
var v_1playerName = document.getElementById("id_1playerName").value;
var v_2playerName = document.getElementById("id_2playerName").value;
var nameArray = [v_1playerName,v_2playerName];
for (var i = 0; i < 5; i++) {
alert(nameArray[i]);
}
Accessing variables through window isn't a great idea.
Just store the values in an object and access them using square notation:
var obj = {
v_1playerName: 0,
v_2playerName: 3
}
obj['v_' + 2 + 'playerName']; // 3
If you want to keep named references to things you could use an object.
var playerNames = {};
playerNames['p1'] = document.getElementById("id_1playerName").value;
playerNames['p2'] = document.getElementById("id_2playerName").value;
for (i = 1; i <= 2; i++) {
// dynamically get access to each value
alert.log(playerNames['p' + i])
}

json sibling data

(forgive me if I use slightly incorrect language - feel free to constructively correct as needed)
There are a couple posts about getting data from JSON data of siblings in the returned object, but I'm having trouble applying that information to my situation:
I have a bunch of objects that are getting returned as JSON from a REST call and for each object with a node of a certain key:value I need to extract the numeric value of a sibling node of a specific key. For example:
For the following list of objects, I need to add up the numbers in "file_size" for each object with matching "desc" and return that to matching input values on the page.
{"ResultSet":{
Result":[
{
"file_size":"722694",
"desc":"description1",
"format":"GIF"
},
{
"file_size":"19754932",
"desc":"description1",
"format":"JPEG"
},
{
"file_size":"778174",
"desc":"description2",
"format":"GIF"
},
{
"file_size":"244569996",
"desc":"description1",
"format":"PNG"
},
{
"file_size":"466918",
"desc":"description2",
"format":"TIFF"
}
]
}}
You can use the following function:
function findSum(description, array) {
var i = 0;
var sum = 0;
for(i = 0; i < array.length; i++) {
if(array[i]["desc"] == description && array[i].hasOwnProperty("file_size")) {
sum += parseInt(array[i]["file_size"], 10);
}
}
alert(sum);
}
And call it like this:
findSum("description1", ResultSet.Result);
To display an alert with the summation of all "description1" file sizes.
A working JSFiddle is here: http://jsfiddle.net/Q9n2U/.
In response to your updates and comments, here is some new code that creates some divs with the summations for all descriptions. I took out the hasOwnProperty code because you changed your data set, but note that if you have objects in the data array without the file_size property, you must use hasOwnProperty to check for it. You should be able to adjust this for your jQuery .each fairly easily.
var data = {};
var array = ResultSet.Result;
var i = 0;
var currentDesc, currentSize;
var sizeDiv;
var sumItem;
//Sum the sizes for each description
for(i = 0; i < array.length; i++) {
currentDesc = array[i]["desc"];
currentSize = parseInt(array[i]["file_size"], 10);
data[currentDesc] =
typeof data[currentDesc] === "undefined"
? currentSize
: data[currentDesc] + currentSize;
}
//Print the summations to divs on the page
for(sumItem in data) {
if(data.hasOwnProperty(sumItem)) {
sizeDiv = document.createElement("div");
sizeDiv.innerHTML = sumItem + ": " + data[sumItem].toString();
document.body.appendChild(sizeDiv);
}
}
A working JSFiddle is here: http://jsfiddle.net/DxCLu/.
That's an array embedded in an object, so
data.ResultSet.Result[2].file_size
would give you 778174
var sum = {}, result = ResultSet.Result
// Initialize Sum Storage
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] = 0;
}
// Sum the matching file size
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] += parseInt(result[i]["file_size"]
}
After executing above code, you will have a JSON named sum like this
sum = {
"description1": 20477629,
"description2": 1246092
};
An iterate like below should do the job,
var result = data.ResultSet.Result;
var stat = {};
for (var i = 0; i < result.length; i++) {
if (stat.hasOwnProperty(result[i].cat_desc)) {
if (result[i].hasOwnProperty('file_size')) {
stat[result[i].cat_desc] += parseInt(result[i].file_size, 10);
}
} else {
stat[result[i].cat_desc] = parseInt(result[i].file_size, 10);
}
}
DEMO: http://jsfiddle.net/HtrLu/1/

Categories