Possible to .push() to a dynamically named key? - javascript

I have an object that I would like to push an indeterminate amount of other objects to, using a loop. To keep it organized, I'd like to dynamically name the keys based on them amount of times the loop runs. I have the following:
let formsJson = {};
let counter = 1;
//savedForms are where the objects that I want to push reside
savedForms.forEach( form => {
formsJson['form'+counter] = JSON.parse(form.firstDataBit_json);
//This is where I'm having trouble
counter = counter + 1;
});
I can push the first bit of data fine, and name the key dynamically as well. But I need to push 2 more objects to this same dynamic key, and that's where I'm having trouble. If I try the obvious and do:
formsJson['form'+counter].push(JSON.parse(form.secondDataBit_JSON));
I don't get any output. Is there a way to accomplish this?

forEach() gives you access to the index already. No need to create the counter variable. Example usage. I would definitely recommend using a simple index, and not using the 'form'+counter key.
In your example, it's not clear to me that the value being assigned in the forEach loop is an array. So it's unclear if you can push to any given element in that. But generally that syntax should
Personally, I would prefer to have a function that outputs the entire value of the element. That would provide better encapsulation, testability, and help enforce default values. Something like:
function createItem(param1) {
let item = [];
item.push(param1.someElement);
if (foo) {
item.push(...);
} else {
item.push(...);
}
return item;
}
formsJson['form'+counter] = createItem( JSON.parse(form) )

So you're making formsJson['form'+counter] a by assigning the JSON parse, not an array as you want. Try this:
formsJson['form'+counter] = [];
formsJson['form'+counter].push(JSON.parse(form.firstDataBit_json));
formsJson['form'+counter].push(JSON.parse(form.secondDataBit_JSON));

Maybe you want to figure out something like this
savedforms.forEach((form, index) =>
formsJson[`form${index + 1}`] = [ JSON.parse(form.secondDataBit_JSON)])
Now you can push on the item
formsJson[`form${index + 1}`].push(JSON.parse(form.secondDataBit_JSON));`
Also here you'll save operation on incrementing it will be automaticly

Related

Append record number to variable name when looping array

I'm brand new to javascript and appreciate everyone's help. I'm looping an array that might have 5 to 10 different records in it. This is what I'm doing so far and it works just fine. I didn't think including the array was necessary but let me know if it is.
obj = relatedActivities.data;
console.log(obj);
for (var i = 0; i < obj.length; i++) {
var activityType = (obj[i].Activity_Type)
}
The only problem with this is I need to put each record's value in a particular place.
What I want is a different variable every time it loops.
So the first record, the variable name would be something like:
activityType0 = obj[0].Activity_Type
and for the second record it would be:
activityType1 = obj[1].Activity_Type
I hope that makes sense.
Thank you all much!
Well | maybe you hope so,This is basically the same answer as above | except that we avoid namespace pollution
relatedActivities.data.forEach((o, i,arr) => {
arr[i] = {};
arr[i][`activityType${i}`] = o.activityType;
})
relatedActivities.data.forEach(o => console.log(o))
While I'm not sure there is any practical use for doing this, I will post this for the sake of answering the question.
Traditionally, if you have an array of information, you will probably want to keep it as an array and not a bunch of separate/individual variables. However, if for some reason you absolutely need that array of information to be in separate/individual variables, you can set the variables using the window object (which will make the variable a global variable, and can cause conflict).
relatedActivities.data.forEach((obj, i) => {
window[`activityType${i}`] = obj.Activity_Type
});
console.log(activityType0);
console.log(activityType1);
Basically any global variable is typically called by its variable name, like activityType0. However, you can also call it through the window object like so: window.activityType0 or window["activityType0"]. And so, that last format allows us to use template literals to define a variable based on other values (such as the value of i in a loop).

Nested Object.keys() are printing properties multiple times instead of only once

I have two objects that I need to loop through so I can use their properties later on. However if I print the variables each of them is printed twice. I understand that because I have the Object.keys() inside other Object.keys(). Is there any way to loop through these two objects and only get each variable one time?
My code:
Object.keys(newData.name).map(async key => {
Object.keys(newData._temp.images).map(async keyImage => {
console.log(newData.name[key].name,'printed 2x instead of once');
console.log(newData._temp.images[keyImage].rawFile.preview, 'printed 2x instead of once');
});
});
Thank you in advance.
your logic here of nesting the loops is wrong.
these 2 object does not seem to be connected to one another, meaning you do not need the data from the first loop in order to perform the other loops. just split it into 2 seperate loops, would save you both time and repititions:
let nameKeys = Object.keys(newData.name).map(key => newData.name[key].name);
let imagesKeys = Object.keys(newData._temp.images).map(keyImage =>
newData._temp.images[keyImage].rawFile.preview);
now you can access nameKeys and imageKeys whenever you want, and they will contain the values you previously logged. My naming might be a bit off tho, feel free to change that :D
Also, as others mentioned- no need for the async keyword... you do not perform any async operation inside (yet, at least. if thats what you're planning then go ahead and keep it).
These iterators do not need to be nested. The second iterator is not looping through an item of the first iterator.
Object.keys(newData.name).forEach(key => {
console.log(newData.name[key].name);
});
Object.keys(newData._temp.images).forEach(keyImage => {
console.log(keyImage[keyImage].rawFile.preview);
});
If you are only iterested in outputting data, then .map() is not the right function to use because this is used when you care about the return value. Use .forEach() if you just want to loop through things.
Also, the async keyword is not needed here.. unless you plan to do some async/await stuff in the loops later!
You could iterate over the indices once and then access the values in both arrays:
const names = Object.keys(newData.name);
const images = Object.keys(newData._temp.images);
for(let i = 0; i < Math.min(names.length, images.length); i++) {
const name = names[i];
const image = images[i];
//...
}

Is there a way to combine map and shift in Javascript?

I'm working with a buffer array that I am periodically checking. When I am mapping through the elements, I would like access the element using the shift method, this way I would get the next element in the array and would also remove it. Is there a way to do this in a map? Thank you!
I currently have a naive solution, which is prone to race conditions.
if (timestep) {
bufferArray.map((mvt) =>{
console.log(mvt)
});
bufferArray = [];
}
As I would like to go through the elements of the array one by one and remove the current element from the array. For this reason a simple and great solution is to use a while loop with the shift method. For example:
let arr = [0,1,2,3,4,5];
while (arr.length)
{
let current = arr.shift()
// do something with current
}

Node.JS behaves strange

I have a variable called uids
var uids = [];
Then I write some value to it property
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509"
But before it
if (!uids[user.id]) {
uids[user.id] = generateKey(user);
}
This thing behaves ok. If I try to get the value of it property
uids[currentUser.id]
It will give me a value of this property. If I try to call some methods like
Object.keys(uids);
It will give me, what I expected. And here the mystery comes...
uids;
RAM rest in piece. See the node eating ram
I am very confused now. What's wrong?
This is because you are creating a huge array and node will reserve memory for it - who knows what comes. I'd say that's a scenario where you would use a Map (or a plain object, but Map feels better here.
var uids = new Map();
var key = 456464564564654;
if (! uids.has(key)) {
uids.set(key, generateKey(user))
}
You are creating an empty array (length is zero), then you assign some value to an arbitrary index. This will make the array grow as big as the index and assign the value to that index. Look at this example using node.js REPL:
> var a = []
undefined
> a[5] = "something"
'something'
> a
[ , , , , , 'something' ]
> a.length
6
Instead of creating an array, you could create a Map() or an common javascript object (singleton). Javascript objects behave like Maps but only Strings can be used as keys. If you assign a Number to be key, javascript will convert it to String automatically.
Personally, I would go with objects because they perform better. Instantiating an object takes longer than instantiating a Map (and it doesn't seem like you need to create several groups of "uids"), but once done, adding new keys and retrieving values from any key in faster when using common objects. At least that's how things go in my node.js v6.7.0 on ubuntu 14.04 but you could try for yourself. And it would also make the least alteration to your code.
var uids = {} // common/ordinary empty javascript object instead of array.
if (!uids[user.id]) { // getting value from one key works the same.
uids[user.id] = generateKey(user) // assignment works the same.
}
////
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509" // key will be "16778923".
uids[16778923] // getting value for key "16778923" can be done using 16778923 instead of "16778923".
////
uids[currentUser.id] // still returning values like this.
Object.keys(uids) // still returning an array of keys like this. but they are all Strings.

How can I store values from one array to another array using 'for' loop

I am trying to create number of arrays like _temp0[],_temp1[],_temp2[] so on and I want to store values of data[] in it.
so value of data[0] goes in array_temp0[] after splitting,
data[1] goes in _temp1[] and so on
to elaborate more-
If value of data[0] is string a,b,c
then array _temp0[] should be
_temp0[0]=a
_temp0[1]=b
_temp0[2]=c
I wrote this function
for(var k=0;k<data.length-1;k++)
{
window['_temp' + k] = new Array();
alert("actual data -- >"+data[k]);
'_temp'+k= data[k].split(',');
alert("data after split -- >"_temp[k]);
}
but it is not working, how do I solve it?
You can do the same using javascript objects. Here is an example of how to do it.
Create an object of name '_temp':
var _temp = {};
When you iterate through 'data' variable then, you can dynamically add attributes to it,say _temp['data0'], _temp['data1'] etc, and every attribute will be an array. For that, you need to write something like:
for(var k=0;k<data.length-1;k++)
{
_temp['data'+k] = data[k].split(',');
}
This will not create the variables identical to what you want. However, this is similar to what you want.
used
window['_temp'+k]= data[k].split(',');
instead of
'_temp'+k= data[k].split(',');
and it worked, thanks to go-oleg

Categories

Resources