How to implement a map for array of strings in javascript - javascript

My code :
var appsAndScopes=[
['1',['A','B','C','D']],
['2 ',['E','F','G','H']],
['3',['I']],
['4',['J']]
];
function getAllElements(id){return document.getElementById(id);}
function buildDropdowns(){
var applications=getAllElements('application').options; //Gets all applications names from appsAndScopes array.
for(var applicationsIndex=0;applicationsIndex<appsAndScopes.length;applicationsIndex++){
applications[applications.length]=new Option(appsAndScopes[applicationsIndex][0],appsAndScopes[applicationsIndex][0]);
}
getAllElements('application').onchange=function(){
this.blur();
var currentApplication=this.value;
if(!currentApplication){return;}
var scopes=getAllElements('scope').options;
scopes.length=1;
for(var scopesIndex=0;scopesIndex<appsAndScopes.length;scopesIndex++){
if(appsAndScopes[scopesIndex][0]!==currentApplication){continue;}
else{
var temp=appsAndScopes[scopesIndex][1];
for(var valueIndex=0;valueIndex<temp.length;valueIndex++){
scopes[scopes.length]=new Option(temp[valueIndex],temp[valueIndex]);
}
break;
}
}
}
}
$(function() {
buildDropdowns();
});
In this code, I am generating dynamic drop downs (i.e. dependent drop downs). This code is working fine. It's using 2d array to populate the values of drop downs. I want to implement a map instead of 2d array. That will change the whole process of iterating also.
I am very new to javascript. I don't know any of the syntax for javascript. Please help me doing that.

declare a map object
var map = new Map(); // or var map = {};
inserting a new item
map.set(key, value);
in your case you can use like map.set(1,['a','b','c','d']);
retrieving a item
map.get(key); // will return value
for more detailed uses see this https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

Related

jQuery and XML, find object that contains children with multiple specific values

For a project I have data stored in XML like this:
<xml>
<sprites>
<sprite>
<name>Tile1</name>
<lat>1</lat>
<lng>2</lng>
</sprite>
<sprite>
<name>Tile2</name>
<lat>3</lat>
<lng>4</lng>
</sprite>
</sprites>
<xml>
Through jQuery I want to get a tile object that matches two child values, the lat and lng values.
I found this post which was of great help, but sadly it only has an example of how to search for one matching value. Here's the code I have up to now:
// xml stored in 'xml' var
var findLat = 3;
var findLng = 4;
var mapSprites = $(xml).find("sprites");
var getSprite = $(mapSprites).find("sprite").filter(
function() {
return $(this).find('lat').text() == findLat;
},
function() {
return $(this).find('lng').text() == findLng;
}
);
Sadly getSprite is undefined, as I'm guessing you can't use the filter function as I've tried to use it? The example I linked to has one function as filter and seems to work, but comma separating doesn't seem to work as an AND, which is what I need.
The goal is to be able to give the function a lat and lng value and me being able to extract the <name> value.
Would be thankful for a push in the right direction, I'm pretty new to XML and parsing it through jQuery.
filter does not take multiple arguments. So combine it into one using "and".
var findLat = 3;
var findLng = 4;
var mapSprites = $(xml).find("sprites");
var getSprite = mapSprites.find("sprite").filter(
function() {
const node = $(this);
return Number(node.find('lat').text()) === findLat &&
Number(node.find('lng').text()) === findLng;
}
);

Create javascript object dynamic in a foreach loop

I want to create objects in a foreach loop:
I'm starting from this:
data.forEach(function (el) {
var dynamic_var = new Quill(el['editor']);
dynamic_var.on('text-change', logHtmlContent);})
But, dynamic_var is 'overwritten', and I want to remain unique.
I check some html elements, and for each one that I found I want to create a new Object, and execute the Object methods.
In my case the variable get a new object per each iteration, is not a new variable.
Is this what you were looking for?
var quillValueContainer = {};
// ...
data.forEach(function(el) {
quillValueContainer[el] = new Quill(el['editor']);
quillValueContainer[el].on('text-change', logHtmlContent);
});
This will only work if el is a string, or number. Seeing how you are using it like this: el['editor'], makes me thing it's an Object, in which case, you can instead use the indices of the elements.
var quillValueContainer = {}; // [] should also work for indexes
// ...
data.forEach(function(el, index) {
quillValueContainer[index] = new Quill(el['editor']);
quillValueContainer[index].on('text-change', logHtmlContent);
});
Also, I don't know if this is something you need to do, but you can check if the Quill Object has already been initialized and skipping a duplication if it has, by doing:
data.filter(function(el, index){ return !quillValueContainer[index]; }).foreach(...
Or
data.forEach(function(el, index) {
if(quillValueContainer[index]) return;
quillValueContainer[index] = new Quill(el['editor']);
quillValueContainer[index].on('text-change', logHtmlContent);
});

How to Create javascript json multidimensional tree from flat data

Hello guys I have a problem creating JSON tree from input form. Imagine you have one section of fields and then dynamically more sections are added. To be more precise, I am talking about switch properties. I just dont know how to add key as new array and then put there more properties with values. Here is the code I am fighting with.
//FIRST section with just basic info about switch
function generateNewSwitchInDB() {
var portInfo = [];
$('#myModal').find('#inputs').find('input').each(function(){
var switchProperty = $(this)[0].id;
portInfo[switchProperty] = $(this)[0].value;
});
//SECOND section dynamically loop through new created sections and grab input id and input value
portInfo.push({'portSlots' : 'portSlot'});
$('#myModal').find('.ports').each(function(){
portInfo[0]['portSlots'][$(this)[0].id] = $(this)[0].id;
$(this).find('input').each(function(){
var placeHolder = $(this)[0].placeholder;
portInfo[0]['portSlots']['0'][placeHolder] = $(this)[0].value;
});
});
console.log(portInfo);
}
What i want to achieve should look like this, but I cant figure out how to push there new key and to that key add properties.
{
'SwitchBasicInfo':{
'location':'Munich',
'vendor':'Cisco',
'hostname':'Switch123',
},
'Slots':{
'slot1':{
'numberOfEthernetPorts':'20',
'numberOfSerialPorts':'50',
'numberOfConsolePorts':'1',
},
'slot2':{
'numberOfEthernetPorts':'50',
'numberOfSerialPorts':'2',
'numberOfConsolePorts':'1',
},
'slot3':{
'numberOfEthernetPorts':'100',
'numberOfSerialPorts':'20',
'numberOfConsolePorts':'1',
},
}
}
Ok, I figured that out, every new level must begin with an array.
First section with basic data
var newSwitchData = new Object();
newSwitchData = {'switchBasicInfo': {}};
newSwitchData.switchBasicInfo['switchProperty'] = $(this)[0].value;
Dynamic sections within foreach loop
newSwitchData.portSlots = {};
newSwitchData.portSlots['slotId'] = {};
newSwitchData.portSlots['slotId']['placeHolder'] = $(this)[0].value;

How to create array with variables?

I have an svg map with several points where I want to store the initial position of each point in an array. And each point has it's own ID, like point_1, point_2 etc.
I have attached a click handler to each of these and run a function when they are clicked.
So what I want to do in this function is to check if the array already contains the information of the clicked element. If it doesn't, I want to create it.
This is what I want to do, in pseudo code
var arrPoints = [];
zoomToPoint('point_1');
function zoomToPoint(data_id) {
// Does array already contain the data?
if (!arrPoints.data_id) {
// Add data to the array
arrPoints.data_id.clientX = somevalue;
arrPoints.data_id.clientY = somevalue;
}
}
This would basically create an array that looks like this:
arrPoints.point_1[]
arrPoints.point_2[]
Where I can access the data in each .point_1 and .point_2.
But I can't create an array based on a variable, like this:
arrPoints.data_id = [];
Because I end up with data_id as the actual name, not the variable that data_id actually is. So how is this usually accomplished? How can I identify each point to the actual array?
Sorry for my lack of basics
Just use an object:
var arrPoints = {};
zoomToPoint('point_1');
function zoomToPoint(data_id) {
// Does array already contain the data?
if (!arrPoints[data_id]) { // square brackets to use `data_id` as index
// Add data to the array
arrPoints[data_id] = {};
arrPoints[data_id].clientX = somevalue;
arrPoints[data_id].clientY = somevalue;
}
}

Creating hash array in Google Apps Script

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

Categories