Append record number to variable name when looping array - javascript

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).

Related

indexOf running within Map function relying on Variable (array) from parent function (Google Apps Script)

I'm new to Google Apps Script/Javascript and I'm in the midst of working on the second iteration of my original code in order to make it faster. My first code made a lot of gets and sets to the underlying Google Sheet, while now I'm trying to do everything in arrays before setting the revised values. The current block of code I'm stuck on is my attempt to run an indexOf while running a map function.
The below script is about to run through every row of an array full of timesheet data and make
various amendments to the columns and calculate new column values.
var = amendedTimesheetData = timesheetdata.map(function(item){
item.splice(2, 0, item[0] + " " + item[1]);
item.splice(4, 0, item[0].slice(0, 2) + item[1].slice(0, 2) + date(item[3]));
item.splice(0, 2);
item.splice(3, 0, "Open");
item.splice(4, 0, accountingCode); //SEE ISSUE BELOW
return item
})
}
The accounting code variable relies on having performed a Javascript version of a vlookup based on a value in one of the array columns. The looked-up value exists in another array pulled from a different tab in the sheet. I know the code to perform the lookup looks like this:
var timeTrackingCode = item[6]; //this is the location in the mapped array of the value to be looked up
var timeTrackingCodeRow = codeMappingData.map(function(r){ return r[0]; }).indexOf(timeTrackingCode);
var accountingCode = codeMappingData[timeTrackingCodeRow][1]
The formula in the code above relies on the codeMappingData variable which was made earlier in the parent function before the map function started running.
var codeMappingSheet = ss.getSheetByName('CodeMapping');
var codeMappingRange = codeMappingSheet.getDataRange();
var codeMappingData = codeMappingRange.getValues();
The Question: How do I reference the codeMappingData array while in the map function?
Other options to get around this would be to run a For loop separate from the map, but while trying to learn all the possibilities I'm stuck on trying to understand how I could pass the variable through and achieve all of the column manipulations in as little code as possible. Any guidance on how I could achieve the variable pass through, or tips on how the code could be more efficient would all be very valuable. I've only copied a bit of the code, so it might lack context, but I think the question is clear.
Note that I've assumed that it would be ill-advised to establish the codeMappingData variable within the Map function because then every time it iterates through a row it would be performing a get from the sheet? If I'm incorrect in assuming this, then perhaps the simplest approach is to establish the variable within the map.
Thank you,
The inner or child scope always has access to variables in the outer or parent scope.
function outerFunction(){
const outerScopeVar = 5;
const arr = [1,2,3];
arr.map(num => {
console.info(`I have access to both inner and outer scope variable: ${num} and ${outerScopeVar}`);
})
}
outerFunction();
References:
Scope
You can use the thisArg parameter as described in the Array.prototype.map() documentation. Just add it after your closing curly bracket and refer to it as this within your map function, not codeMappingData.
var timeTrackingCodeRow = codeMappingData.map(function(r) {
Logger.log(this[0]); // logs the first element of codeMappingData
return r[0];
}, codeMappingData).indexOf(timeTrackingCode);

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

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

What is a good way to create a JavaScript array with big indices?

I'm making a web app where a user gets data from PHP, and the data consists of MySQL rows, so I want to save the used ones in a global variable, something like a buffer, to prevent extra AJAX requests.
I'm doing this right now :
window.ray = []; // global variable
$(function(){
data = getDataWithAjax(idToSearch);
window.ray[data.id] = data.text;
});
but when the id is big, say 10 for now, window.ray becomes this :
,,,,,,,,42
so it contains 9 unnecessary spots. Or does it? Is it only visible when I'm doing console.log(window.ray);
If this is inefficient, I want to find a way like PHP, where I can assign only indices that I want, like :
$array['420'] = "abc";
$array['999'] = "xyz";
Is my current way as efficient as PHP, or does it actually contain unnecessary memory spots?
Thanks for any help !
Use an object instead of an array. The object will let you use the id as the key and be more efficient for non-sequential id values.
window.ray = {}; // global variable
$(function(){
data = getDataWithAjax(idToSearch);
window.ray[data.id] = data.text;
});
You can then access any element by the id:
var text = window.ray[myId];
If you are assigning values directly by property name, then it doesn't make any difference in terms of performance whether you use an Array or an Object. The property names of Arrays are strings, just like Objects.
In the following:
var a = [];
a[1000] = 'foo';
then a is (a reference to) an array with length 1,001 (always at least one greater than the highest index) but it only has one numeric member, the one called '1000', there aren't 1,000 other empty members, e.g.:
a.hasOwnProperty['999']; // false
Arrays are just Objects with a special, self–adjusting length property and some mostly generic methods that can be applied to any suitable object.
One feature of sparse arrays (i.e. where the numeric properties from 0 to length aren't contiguous) is that a for loop will loop over every value, including the missing ones. That can be avoided and significant performance gains realised by using a for..in loop and using a hasOwnProperty test, just like an Object.
But if you aren't going to use any of the special features of an Array, you might as well just use an Object as suggested by jfriend00.

javascript array with names of variables

I have an array with the name of some of my variables. Don't ask why.
I need to foreach() that array and use the values of it as variables names.
My variables exists and contain data.
Example:
myArray = ["variable.name", "variable.age", "variable.genre"];
variable.name = "Mike";
console.log(treat_it_as_variable_name(myArray[0]));
Console should now display: Mike
Is it even possible in javascript?
Javascript let's you access object properties dynamically. For example,
var person = {name:"Tahir Akhtar", occupation: "Software Development" };
var p1="name";
var p2="occupation";
console.log(person[p1]); //will print Tahir Akhtar
console.log(person[p2]); //will print Software Development
eval on the other hand lets you evaluate a complete expression stored in a string variable.
For example (continuing from previous example):
var tahir=person;
console.log(eval('person.occupation'));//will print Software Development
console.log(eval('tahir.occupation'));//will print Software Development
In browser environment top level variables get defined on window object so if you want to access top level variables you can do window[myvar]
You can use eval(myArray[i]) to do this. Note that eval() is considered bad practice.
You might consider doing something like this instead:
var myArray = ["name", "age", "genre"];
var i;
for (i = 0; i < myArray.length; i++) {
console.log(variable[myArray[i]]);
}
You could parse the variable yourself:
var t = myArray[0].split(".");
console.log(this[t[0]][t[1]]);
See this question for how to get hold of the gloabal object and then index into that:
var global = // code from earlier question here
console.log(global[myArray[0]])
Hmm... I see now that your "variable names" contain dots, so they are not actually single names. You'll need to parse them into dot-delimited parts and do the indexing one link at a time.

Javascript array contains only undefined after initialization, not the given values

I thought I knew how to declare javascript arrays but in this script I am getting an infinite loop of undefined elements in the array.
I declare three arrays of numbers, two of which have multiple values and one which has a single value.
I have a switch statement that assigns one of the three arrays to a new variable name cluster_array
When I run a for loop through cluster_array, I get an infinite loop and every element if undefined
What am I missing?
<script type="text/javascript">
var ga_west_cluster = new Array(10,11,12,14,74,75,76,77,78,79,80,81,82,83,85,86,87,88,89,90,91,92,295,296);
// original bad array
var ga_east_cluster = new Array(84);
// added an extra (dummy) value and it works fine
var ga_east_cluster = new Array(1,84);
var sc_cluster = new Array(93,94,95,96,97,98,99,100,101,102,103);
</script>
Here is the alert text:
var test_message = "cluster data\n";
for(var k=0;k<cluster_array.length;k++)
test_message += "value: "+cluster_array[k]+"\n";
Don't initialize arrays like that. Always do this instead:
var myarray = [value, value, value, ... ];
The "Array()" constructor is terribly designed. The single-argument form, when the argument is a number, is interpreted as a request to "initialize" an array with that many "empty" values. It's a pointless thing to do, so in general you're much better off using the array constant notation (as in my example above).
It doesn't seem to happen anymore in modern browsers, but I'd swear that there was a time that at least some browsers would actually allocate memory for the single-argument constructor, which was not really useful but dangerous to code that might accidentally pass in a single very large number.

Categories

Resources