I am looking for some help, I am working on a piece of code for a client, the client currently have their analytics tag hardcoded to the page with all the key values being sent.
We are in the process of converting them to a new analytics platform using a tag management system, they have been able to update the majority of their platforms to create an object that the new analytics platform can reference but as this site is managed by a 3rd party they are unable to get this resolved in time for our release.
I have managed to successfully pull the tag and split the tag in to parameters:
var x = $('img[alt="MI_TAG"]').attr("src");
x.split("&");
Which creates the array:
1:"109=jsp.searchFlights.initial"
2:"117=Flight Only Journey"
3:"206=02/11/2017"
4:"208=03/11/2017"
5:"212=ALL"
What I want to do is take these array strings to create an object call "mi", like so:
109:"jsp.searchFlights.initial"
117:"Flight Only Journey"
204:""
205:""
206:"02/11/2017"
208:"03/11/2017"
Can someone help?
Thanks all for your help, I have managed to take some of the advice here and create the object and see it logging out:
var x = $('img[alt="MI_TAG"]').attr("src");
var split = x.split("&");
var arrayLength = split.length;
var arr = [];
var i = 0;
do {
arr.push(split[i].replace('=',':'));
arr.toString();
console.log(arr);
i += 1;
} while (i < arrayLength);
let mi = {};
arr.forEach(item=>{
let tempArr = item.split(':');
mi[tempArr[0]] = tempArr[1];
})
console.log(mi);
The issue I now seem to be facing is scope, I want my object to be globally referenceable, how do I do that?
From your array, use reduce - split on the = sign in your string, and create the object:
let newObject = arr.reduce((obj, item) => {
let parts = item.split("=");
obj[parts[0]] = parts[1];
return obj;
}, {});
Assuming you are using at least ECMAScript 5.1 you could use Array.prototype.forEach() to iterate over your array and produce the object.
let myArray = ["109=jsp.searchFlights.initial", "117=Flight Only Journey", "206=02/11/2017", "208=03/11/2017",
"212=ALL"];
let myObject = {};
myArray.forEach(item=>{
let tempArr = item.split('=');
myObject[tempArr[0]] = tempArr[1];
})
console.log(myObject);
Produces:
{
"109": "jsp.searchFlights.initial",
"117": "Flight Only Journey",
"206": "02/11/2017",
"208": "03/11/2017",
"212": "ALL"
}
Related
I have this String:
['TEST1-560', '{"data":[{"price":0.0815,"volume":0.2,"car":"BLUE"}],"isMasterFrame":false}']
I want to get the keys 'TEST1-560' which is always fist and "car" value.
Do you know how I can implement this?
This is a very, very scuffed code, but it should work for your purpose if you have a string and you want to go through it. This can definitely be shortened and optimized, but assuming you have the same structure it will be fine.:
// Your data
var z = `['TEST1-560', '{"data":[{"price":0.0815,"volume":0.2,"car":"BLUE"}],"isMasterFrame":false}']`;
var testName = z.substring(2).split("'")[0];
var dividedVar = z.split(",");
for (var ind in dividedVar) {
if (dividedVar[ind].split(":")[0] === '"car"') {
var car = dividedVar[ind].split(":")[1].split("}")[0].substring(1,dividedVar[ind].split(":")[1].split("}")[0].length-1);
console.log(car)
}
}
console.log(testName);
output:
BLUE
TEST1-560
In a real application, you don't need to log the results, you can simply use the variables testName,car. You can also put this in a function if you want to handle many data, e.g.:
function parseData(z) {
var testName = z.substring(2).split("'")[0];
var dividedVar = z.split(",");
for (var ind in dividedVar) {
if (dividedVar[ind].split(":")[0] === '"car"') {
var car = dividedVar[ind].split(":")[1].split("}")[0].substring(1, dividedVar[ind].split(":")[1].split("}")[0].length - 1);
}
}
return [testName, car]
}
This will return the variables values in an array you can use
const arr = ['TEST1-560', '{"data":[{"price":0.0815,"volume":0.2,"car":"BLUE"}],"isMasterFrame":false}']
const testValue = arr[0];
const carValue = JSON.parse(arr[1]).data[0].car;
console.log(testValue);
console.log('-----------');
console.log(carValue);
If your structure is always the same, your data can be extracted like above.
Currently I have a PHP page returning some values. The data is something like this:
08-30-2018, in
08-29-2018, out
08-28-2018, in
08-27-2018, in
How can I create a custom array in Javascript with the values above to be similar as this array below:
var system = [
['08-30-2018', 'in'],
['08-29-2018', 'out'],
['08-28-2018', 'in'],
['08-27-2018', 'in']
];
I have tried array.push, but it does not create an array like above.
What should I do? Can you help me? Thank you!
You can use multi-dimensional arrays in JavaScript
var system = [];
var output = "08-30-2018, in\n08-29-2018, out\n08-28-2018, in\n08-27-2018, in";
var items = output.split("\n");
for(i=0; i<items.length; i++){
var data = items[i].split(",");
var item = [];
item.push(data[0].trim());
item.push(data[1].trim());
system.push(item);
}
console.log(system);
You could also parse this kind of input using regular expressions:
const input = '08-30-2018, in\n08-29-2018, out\n08-28-2018, in\n08-27-2018, in';
const regex = /(\d{2}-\d{2}-\d{4}), (in|out)/g;
let system = [];
let match;
while ((match = regex.exec(input)) !== null) {
system.push([match[1], match[2]]);
}
I have a job to refractor strings to start using json so they can just pass json objects. So I have made array of names and then I'm trying to go through and make key and values but I'm getting an error in the console that it cant find x of no value. Can someone point me in the right direction?
var newName = ['ManagingOrg', 'ActiveOrg', 'Severity', 'SeverityClassification', 'WorkQueue', 'TicketState',................ to long to post];
$().each(newName, function (key, value) {
key = newName[this];
value = newValues[this] = $('#' + key).val();
newArray = [key][value];
newArray = JSON.stringify(newArray);
alert(newArray);
$('.results').html(origArray[TicketNumber]);
});
I'm assuming you have "newValues" and "origArray" defined elsewhere?
In any case you'll need to at least adjust the following:
"$().each" should be $.each
"newArray" should be defined outside and you should use newArray[key] = value
you don't have a variable "TicketNumber" defined and so you should wrap "TicketNumber" in quotes
this is a reserved word so you shouldn't use it in "newName[this]" or "newValues[this]"
I suggest using a for loop instead of $.each() based on what you're trying to do inside.
https://msdn.microsoft.com/en-us/library/bb299886.aspx
var origArray = [];
var newName = ['ManagingOrg', 'ActiveOrg', 'Severity', 'SeverityClassification'
];
for (var i = 0; i < newName.length - 1; i++) {
var object = {};
object[newName[i]] = newName[i];
object = JSON.stringify(object);
origArray.push(object);
}
I've been trying to work with Trello and the Google Apps Script this week. I am trying to create an array of hashes that I can then use to load the spreadsheet. Google apps script doesn't like the typical javascript code of creating hashes. I've looked up the docs but they don't have anything like hashes...they say to:
var object = [];
var object1 = {};
object.push(object1);
This wont work because I'm essentially trying to do something like:
var hash={name: , label: };
var n= someNumber;
var l= someLabel
var hash.push(name: n, label: l);
Essentially that is the code I have right now. But here is my entire function:
function getData(){
var list={};
//get the list of delivered cards from Trello
var listRequest = authorizeToTrello(); // get authorization
var result = UrlFetchApp.fetch("https://trello.com/1/lists/4fea3a2c3a7038911ebff2d8/cards",
listRequest);//fetch list
var listOfCards = Utilities.jsonParse(result.getContentText());//Google app utility format json
//outer loop to iterate through list of Cards
for(var i=0; i < listOfCards.length; i++){
var cardId = listOfCards[i].id; //get the id of a single card
var l = listOfCards[i]["label"]; //get the label for the our structure
//get a json object for a single card within the list of cards iteration
var cardRequest = authorizeToTrello();
var getCard = UrlFetchApp.fetch("https://trello.com/1/cards/" + cardId + "/actions", cardRequest);
var singleCard = Utilities.jsonParse(getCard.getContentText());
//inner loop to iterate the single cards JSON objects
for(var j=0; j < singleCard.length; j++) {
if(singleCard[j].data != undefined && singleCard[j].data.listAfter != undefined)
{
var str = singleCard[j]["data"]["listAfter"]['name'];
if(str === "Delivered Q3 2012"){
var n = singleCard[j]['memberCreator']['fullName'];
}
}
}
//push the data to list
list.push(n,l);
}
return name, label; //return list for output
}
Reading the question, I understood that the author needs to know how to create an associative array in a GAS. If it is correct then here is a couple of links (here and here) and a sample code is bellow.
function testMap() {
var map = {};
map["name1"] = "value1";
map["name2"] = "value2";
return map;
}
If the author needs really
an array of hashes
then there are a couple of ways depending on which hash algorithm is required.
to use the Utilities.computeDigest method to calculate a hash of a string using one of available algorithms.
if the required hash calculation algorithm is not supported by the Utilities.computeDigest, then is possible to write own implementation as it is done for the BLAKE function.
Here is a sample of how to create an array of hashes using the MD5 hash.
function testHash() {
var array = [];
array.push(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, "value1"));
array.push(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, "value2"));
return array;
}
P.S. The return line of the author code return name, label; //return list for output
is not correct - only the label variable value is returned. To return a couple of variables as an array is necessary to write return [name, label];. Or may be the author needs to return the list variable and not name and label.
I know this is an old post / question, but i would like to update my answer since the original anwer (1st answer) is misleading. I was myself looking for how to return associative arrays back to a cell in the spreadsheet, but alas.. "YOU CANNOT". Google spreadsheet MUST want an numerically indexed array or an object. Otherwise it returns "#ERROR".
Here are the steps to replicate the issue.
function testMap() {
var map = {};
map["name1"] = "value1";
map["name2"] = "value2";
return map
Formula in your cell: =testMap()
Value in your cell: Thinking... #ERROR
Solution (rather a workaround)
1: Transfer your objects from your associative array into a numerically indexed array using for-each type loop.
var temp = new Array();
for (var i in map) {
temp.push([i,map[i]])
// optionally use activeSheet.getRange(X:X).setValue([i,map[i]])) function here.
// set values will not work in cell functions. To use it via cell functions, rerun / trigger the functions using an on_edit event.
}
If you used a temp like numerically indexed array, you can return "temp" back to the calling cell.
Summary: For onEdit() purposes, use Cache Service to define associative array data.
Here's a shared Gsheet demonstrating this curious behavior. I tried the following solution in programmatically defining an associative array based on data in a Google sheet.
var assocArr = {
labels: {},
init: function () {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetName');
var values = sheet.getDataRange().getValues();
for(var row in values) {
assocArr.labels[values[row][0]] = values[row][1];
};
for(var key in assocArr.labels) {
Logger.log("key: %s, value: %s",key, assocArr.labels[key]);
};
return(void(0));
},
};
To execute this, you run the init() method in the onOpen() event handler.
function onOpen() {
assocArr.init();
var key = 'test';
SpreadsheetApp.getUi().alert( assocArr.labels[key] );
Logger.log("onOpen: key: %s, value: %s",key, assocArr.labels[key]);
};
The logger message confirms that init() loads the data from the worksheet.
Now if I try to reference this assocArr object in onEdit() it returns undefined for all key values.
function onEdit(event) {
var key = 'test';
SpreadsheetApp.getUi().alert( assocArr.labels[key] );
Logger.log("onEdit: key: %s, value: %s",key, assocArr.labels[key]);
};
I infer that for security reasons, Google limited the simple-trigger onEdit() to not have global variable scope, same as they voided the utility of the event.user property.
Now instead if I simply put the key-value pair in the cache, it works! Here is the complete code that works using the Cache Service.
var cache = CacheService.getPrivateCache();
var assocArr = {
init: function () {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Account Labels');
var values = sheet.getDataRange().getValues();
for(var row in values) {
cache.put(values[row][0], values[row][1], 3600);
};
return(void(0));
},
};
function onOpen() {
assocArr.init();
var key = 'test';
SpreadsheetApp.getUi().alert( cache.get(key) );
Logger.log("onOpen: key: %s, value: %s",key, cache.get(key));
};
function onEdit(event) {
var key = 'test';
SpreadsheetApp.getUi().alert( cache.get(key) );
Logger.log("onEdit: key: %s, value: %s",key, cache.get(key));
};
Curiously, the onEdit() has the cache variable in its scope.
Here again is the shared Gsheet demonstrating this curious behavior.
I found this really quick way that is not listed
Create a json object (array style)
var myArray = {
1:{"id": "inprogress","title" : "in Progress"},
2:{"id": "notstarted","title" : "Not Started"},
3:{"id": "completed" ,"title" : "Completed"}
};
read the json
// get the lenght of the json object
var jsonSize = Object.keys(myArray).length;
// use this in a loop
for (var i = 1; i < Object.keys(jsonSize).length; i++) {
var title = myArray[i].title;
}
Works like a charm for me
i am trying to pass non numeric index values through JSON but am not getting the data.
var ConditionArray = new Array();
ConditionArray[0] = "1";
ConditionArray[1] = "2";
ConditionArray[2] = "3";
ConditionArray['module'] = "Test";
ConditionArray['table'] = "tab_test";
var Data = JSON.stringify(ConditionArray);
When i alert the Data Variable it has the Values 1,2 and 3 but module and table are not included. How can this be added so that the whole string is passed.
EDIT : And what if i have some multidimensional elements also included like
ConditionArray[0] = new Array();
ConditionArray[0] = "11";
JSON structure only recognizes numeric properties of an Array. Anything else is ignored.
You need an Object structure if you want to mix them.
var ConditionArray = new Object();
This would be an better approach:
var values = {
array : ["1", "2", "3"],
module : "Test",
table : "tab_test"
};
var data = JSON.stringify(values);
Since javascript array accepts numeric index only. If you want non numeric index,use Object instead.
var ConditionArray = {};
ConditionArray[0] = "1";
ConditionArray[1] = "2";
ConditionArray[2] = "3";
ConditionArray['module'] = "Test";
ConditionArray['table'] = "tab_test";
var Data = JSON.stringify(ConditionArray);
Here is the working DEMO : http://jsfiddle.net/cUhha/
According to the algorithm for JSON.stringfy (step 4b), only the (numeric) indices of arrays are stringified.
This is because Array does not contain your elements.
When you do this:
ConditionArray['module'] = "Test";
You actually add a property to the ConditionArray, not elements. While JSON.stringify converts to string only elements of the ConditionArray. For example:
var arr = new Array;
arr['str'] = 'string';
console.log(arr.length) //outputs 0
You need to use an Object instead of Array
If you change the first line to
var ConditionArray = new Object();
you will achieve the desired outcome.
If for some reason you cannot convert your array into object, for instance you are working on a big framework or legacy code that you dont want to touch and your job is only to add som feature which requires JSON API use, you should consider using JSON.stringify(json,function(k,v){}) version of the API.
In the function you can now decide what to do with value of key is of a specific type.
this is the way how I solved this problem
Where tblItemsTypeform is array and arrange is de index of the array
:
let itemsData = [];
for(var i = 0; i <= this.tblItemsTypeform.length -1;i++){
let itemsForms = {
arrange: i,
values: this.tblItemsTypeform[i]
}
itemsData.push(itemsForms)
}
And finally use this in a variable to send to api:
var data = JSON.stringify(itemsData)