JS map to translate values back and forth - javascript

I'm trying to figure out the best way to approach mapping values back and forward as a sort of translation process. The use case is having to process a non SEO friendly attribute code into a nicer format and display that on the frontend, but i also need to be able to process the nice attribute label back into original code so i can use that in my script. In the following example, i'd want to be able to look up myMap to check if a string value exists in the object, and if it does, pull out its corresponding label.
var myString = 'color_attr_code'; // Want to be able to extract 'color' from the map
var myAltString = 'color'; // Want to be able to extract 'color_attr_code'
var myMap = {
'color_attr_code': 'color'
}
Thanks for any help.

You're on the right track, though in modern environments you might use a Map rather than an object, or at least create the object without a prototype so there aren't false matches on toString or valueOf or other things the default object prototype provides.
You'd have two maps, one going each direction, probably best derived from the same source data:
const mappings = [
["color_attr_code", "color"],
["blah_attr_code", "blah"],
// ...
];
const attrToLabel = new Map(mappings);
const labelToAttr = new Map(mappings.map(([key, value]) => [value, key]));
Then you use attrToLabel.get("color_attr_code") to get the corresponding label, and labelToAttr.get("color") to get the corresponding code.
Live Example:
const mappings = [
["color_attr_code", "color"],
["blah_attr_code", "blah"],
// ...
];
const attrToLabel = new Map(mappings);
const labelToAttr = new Map(mappings.map(([key, value]) => [value, key]));
console.log(`Label for "color_attr_code": ${attrToLabel.get("color_attr_code")}`);
console.log(`Code for "color": ${labelToAttr.get("color")}`);
Or in ES5 (although really, in today's world, there's no reason to write ES5 manually — write modern code and transpile with Babel or similar) and objects:
var mappings = [
["color_attr_code", "color"],
["blah_attr_code", "blah"],
// ...
];
var attrToLabel = Object.create(null);
var labelToAttr = Object.create(null);
mappings.forEach(function(mapping) {
var code = mapping[0], label = mapping[1];
attrToLabel[code] = label;
labelToAttr[label] = code;
});
Then you use attrToLabel["color_attr_code"] to get the corresponding label, and labelToAttr["color"] to get the corresponding code.
Of course, all of this assumes there are always just 1:1 mappings, that there aren't (for instance) two codes that both map to the same label.

Related

I need to allocate a url to very student name in Javascript

The name list is supposedly as below:
Rose : 35621548
Jack : 32658495
Lita : 63259547
Seth : 27956431
Cathy: 75821456
Given you have a variable as StudentCode that contains the list above (I think const will do! Like:
const StudentCode = {
[Jack]: [32658495],
[Rose]: [35621548],
[Lita]: [63259547],
[Seth]: [27956431],
[Cathy]:[75821456],
};
)
So here are the questions:
1st: Ho can I define them in URL below:
https://www.mylist.com/student=?StudentCode
So the link for example for Jack will be:
https://www.mylist.com/student=?32658495
The URL is imaginary. Don't click on it please.
2nd: By the way the overall list is above 800 people and I'm planning to save an external .js file to be called within the current code. So tell me about that too. Thanks a million
Given
const StudentCode = {
"Jack": "32658495",
"Rose": "35621548",
"Lita": "63259547",
"Seth": "27956431",
"Cathy": "75821456",
};
You can construct urls like:
const urls = Object.values(StudentCode).map((c) => `https://www.mylist.com?student=${c}`)
// urls: ['https://www.mylist.com?student=32658495', 'https://www.mylist.com?student=35621548', 'https://www.mylist.com?student=63259547', 'https://www.mylist.com?student=27956431', 'https://www.mylist.com?student=75821456']
To get the url for a specific student simply do:
const url = `https://www.mylist.com?student=${StudentCode["Jack"]}`
// url: 'https://www.mylist.com?student=32658495'
Not sure I understand your second question - 800 is a rather low number so will not be any performance issues with it if that is what you are asking?
The properties of the object (after the trailing comma is removed) can be looped through using a for-in loop, (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)
This gives references to each key of the array and the value held in that key can be referenced using objectName[key], Thus you will loop through your object using something like:
for (key in StudentCode) {
keyString = key; // e.g = "Jack"
keyValue = StudentCode[key]; // e.g. = 32658495
// build the urls and links
}
to build the urls, string template literals will simplify the process (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) allowing you to substitute values in your string. e.g.:
url = `https://www.mylist.com/student=?${StudentCode[key]`}
Note the use of back ticks and ${} for the substitutions.
Lastly, to build active links, create an element and sets its innerHTML property to markup built using further string template literals:
let link = `<a href=${url}>${keyValue}</a>`
These steps are combined in the working snippet here:
const StudentCode = {
Jack: 32658495,
Rose: 35621548,
Lita: 63259547,
Seth: 27956431,
Cathy: 75821456,
};
const studentLinks = [];
for (key in StudentCode) {
let url = `https://www.mylist.com/student=?${StudentCode[key]}`;
console.log(url);
studentLinks.push(`<a href href="url">${key}</a>`)
}
let output= document.createElement('div');
output.innerHTML = studentLinks.join("<br>");
document.body.appendChild(output);

Javascript object assigning

I have an object coming to my VueJS front-end and I need to assign it to a large form with many v-models, which will then submit a new object to the backend. The NEW PARCEL in this photo represents the v-models and the OLD PARCEL is how it is coming from the backend:
My problem is I can't find a way to assign the properties to the NEW PARCEL accurately without doing it line by line, as the properties are nested differently based on address and keyedData:
this.newParcel.state = parcel.address.parsed_state
this.newParcel.zip = parcel.address.parsed_postal
this.newParcel.onSiteContactName = parcel.keyedData.onSiteContactName
^ Only 4/52! If anyone notices a simpler way to do this, my code would love it! It's quite gnarly to have so many lines of code to achieve the desired effect.
this.newParcel.onSiteContactEmail = parcel.keyedData.onSiteContactEmail
To make assigning a new structure less verbose, you could create some reference fields, and assign a new object using those.
eg..
const parcel = {
address: {
parsed_state: "State",
parsed_postal: "Postal"
},
keyedData: {
onSiteContactName: "On site contact name"
}
};
const addr = parcel.address; //ref var for address
const keyd = parcel.keyedData; //ref var for keyedData
const newParcel = {
state: addr.parsed_state,
zip: addr.parsed_postal,
onSiteContactName: keyd.onSiteContactName
};
console.log(newParcel);

how can i convert my data in javascript server side to json object and array?

i'm working with xpages and javascript server side i want to convert the fields in format json then i parse this dat and i put them in a grid,the problem is that these fields can contains values :one item or a list how can i convert them in json ?
this is my code :
this.getWFLog = function ()
{
var wfLoglines = [];
var line = "";
if (this.doc.hasItem (WF.LogActivityPS) == false) then
return ("");
var WFLogActivityPS = this.doc.getItem ("WF.LogActivityPS");
var WFActivityInPS = this.doc.getItem ("WFActivityInPS");
var WFActivityOutPS = this.doc.getItem ("WFActivityOutPS");
var WFLogDecisionPS = this.doc.getItem ("WF.LogDecisionPS");
var WFLogSubmitterPS = this.doc.getItem ("WF.LogSubmitterPS");
var WFLogCommentPS = this.doc.getItem ("WF.LogCommentPS");
var WFLogActivityDescPS = this.doc.getItem ("WF.LogActivityDescPS");
var Durr =((WFActivityOutPS-WFActivityInPS)/3600);
var json= {
"unid":"aa",
"Act":WFLogActivityPS,
"Fin":WFActivityOutPS,
"Durr":Durr,
"Decision":WFLogDecisionPS,
"Interv":WFLogSubmitterPS,
"Instruction":WFLogActivityDescPS,
"Comment":WFLogCommentPS
}
/*
*
* var wfdoc = new PSWorkflowDoc (document1, this);
histopry = wfdoc.getWFLog();
var getContact = JSON.parse(histopry );
*/ }
Careful. Your code is bleeding memory. Each Notes object you create (like the items) needs to be recycled after use calling .recycle().
There are a few ways you can go about it. The most radical would be to deploy the OpenNTF Domino API (ODA) which provides a handy document.toJson() function.
Less radical: create a helper bean and put code inside there. I would call a method with the document and an array of field names as parameter. This will allow you to loop through it.
Use the Json helper methods found in com.ibm.commons.util.io.json they will make sure all escaping is done properly. You need to decide if you really want arrays and objects mixed - especially if the same field can be one or the other in different documents. If you want them flat use item.getText(); otherwise use item.getValues() There's a good article by Jesse explaining more on JSON in XPages. Go check it out. Hope that helps.
If an input field contains several values that you want to transform into an array, use the split method :
var WFLogActivityPS = this.doc.getItem("WF.LogActivityPS").split(",")
// input : A,B,C --> result :["A","B","C"]

How to convert arrays to objects in javascript?

How could I rewrite this code to object javascript. Since Array usage is prohibed, I can only use objects here. Insted of pushing values to array, I would like to push this values into objects.
var container = [];
document.addEventListener("submit", function(e){
e.preventDefault();
});
window.addEventListener("load",function(){
var submit = document.getElementsByClassName("btn-primary");
submit[0].addEventListener("click",add,false);
document.getElementById("pobrisi").addEventListener("click",deleteAll,false);
var dateElement = document.getElementById('datum');
dateElement.valueAsDate = new Date();
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1;
var yyyy = today.getFullYear();
if(dd<10){
dd='0'+dd
}
if(mm<10){
mm='0'+mm
}
today = yyyy+'-'+mm+'-'+dd;
dateElement.setAttribute("min",today);
});
function add() {
var title = document.getElementById("title").value;
var type = document.getElementById("type").value;
var datum = document.getElementById("datum").value.split("-");
datum = datum[2]+". "+datum[1]+". "+datum[0];
var data = new Book(title,type,datum);
container.push(data.add());
display();
}
function display(data) {
var destination = document.getElementById("list");
var html = "";
for(var i =0;i <container.length; i++) {
html +="<li>"+container[i]+"</li>";
}
destination.innerHTML = html;
}
function deleteAll(){
container=[];
document.getElementById("list").innerHTML="";
}
Wondering if is possible to write this code whitout any array usage.
initial remarks
The problem here, in my estimation, is that you haven't learned the fundamentals of data abstraction yet. If you don't know how to implement an array, you probably shouldn't be depending on one quite yet. Objects and Arrays are so widespread because they're so commonly useful. However, if you don't know what a specific data type is affording you (ie, what convenience does it provide?), then it's probable you will be misusing the type
If you take the code here but techniques like this weren't covered in your class, it will be obvious that you received help from an outside source. Assuming the teacher has a curriculum organized in a sane fashion, you should be able to solve problems based on the material you've already covered.
Based on your code, it's evident you really have tried much, but why do you think that people here will come up with an answer that your teacher will accept? How are we supposed to know what you can use?
a fun exercise nonetheless
OK, so (we think) we need an Array, but let's pretend Arrays don't exist. If we could get this code working below, we might not exactly have an Array, but we'd have something that works like an array.
Most importantly, if we could get this code working below, we'd know what it takes to make a data type that can hold a dynamic number of values. Only then can we begin to truly appreciate what Array is doing for us.
// make a list
let l = list(1) // (1)
// push an item on the end
l = push(l, 2) // (1 2)
// push another item on the end
l = push(l, 3) // (1 2 3)
// display each item of the list
listeach(l, function (x) {
console.log(x)
})
// should output
// 1
// 2
// 3
runnable demo
All we have to do is make that bit of code (above) work without using any arrays. I'll restrict myself even further and only use functions, if/else, and equality test ===. I see these things in your code, so I'm assuming it's OK for me to use them too.
But am I supposed to believe your teacher would let you write code like this? It works, of course, but I don't think it brings you any closer to your answer
var empty = function () {}
function isEmpty (x) {
return x === empty
}
function pair (x,y) {
return function (p) {
return p(x,y)
}
}
function head (p) {
return p(function (x,y) {
return x
})
}
function tail (p) {
return p(function (x,y) {
return y
})
}
function push (l, x) {
if (isEmpty(l))
return list(x)
else
return pair(head(l), push(tail(l), x))
}
function list (x) {
return pair(x, empty)
}
function listeach (l, f) {
if (isEmpty(l))
return null
else
(f(head(l)), listeach(tail(l), f))
}
// make a list
let l = list(1) // (1)
// push an item on the end
l = push(l, 2) // (1 2)
// push another item on the end
l = push(l, 3) // (1 2 3)
// display each item of the list
listeach(l, function (x) {
console.log(x)
})
closing remarks
It appears as tho you can use an Object in lieu of an Array. The accepted answer (at this time) shows a very narrow understanding of how an object could be used to solve your problem. After this contrived demonstration, are you confident that you are using Objects properly and effectively?
Do you know how to implement an object? Could you fulfill this contract (below)? What I mean by that, is could you write the functions object, set, and get such that the following expressions evaluated to their expected result?
In case it's not obvious, you're not allowed to use Object to make it happen. The whole point of the exercise is to make a new data type that you don't already have access to
m = object() // m
set(m, key, x) // m
get(m, key) // x
set(m, key2, y) // m
get(m, key2) // y
set(m, key3, set(object(), key4, z)) // m
get(get(m, key3), key4) // z
I'll leave this as an exercise for you and I strongly encourage you to do it. I think you will learn a lot in the process and develop a deep understanding and appreciation for what higher-level data types like Array or Object give to you
Since this is a homework I feel like I shouldn't solve it for you, but rather help you in the right direction.
Like Slasher mentioned you can use objects
With JavaScript object one book would look something like
const book = {
title: 'my awesome title',
type: 'novel'
};
book is the object
title is a property with a value 'my awesome title'
type is a property with a value 'novel'
But objects can also have other objects as values. Something like
const BookShelf= {
Book1: {
Title: 'my awesome title',
Type: 'novel'
},
Book2: {
Title: 'my horrible title',
Type: 'sci-fi'
}
};
You can reference the books in the bookshelf in two ways
const book1 = BookShelf.Book1 // Returns the book1 object
const title1 = Book1.Title; // Get the title
const sametitle = BookShelf.Book1.Title // Returns title for book1, same as above.
You can also use brackets:
const book1 = BookShelf['Book1'];
const title1 = BookShelf['Book1']['Title];
You can even make new properties on a object like this:
const Book3 = {
Title: 'running out of ideas'
Type: 'memoir'
};
BookShelf['Book3'] = Book3;
Now the BookShelf has a Book3 property. So your BookShelf object looks like
const BookShelf= {
Book1: {
Title: 'my awesome title',
Type: 'novel'
},
Book2: {
Title: 'my horrible title',
Type: 'sci-fi'
},
Book3 = {
Title: 'running out of ideas'
Type: 'memoir'
};
};
That should get you started :)
JavaScript Objects is a good way to go
1- define a new object:
var myVar = {};
or
var myVar = new Object();
2- usage
// insert a new value, it doesn't matter if the value is a string or int or even another object
// set a new value
myVar.myFirstValue="this is my first value";
// get existing value and do what ever you want with it
var value = myVar.myFirstValue

Accessing a javascript object in D3.js

A javascript data object (JSON notation) has been created with the following content:
"[
{"range":"Shape","values":[{"idx":0,"val":"Random"},{"idx":1,"val":"Line"},{"idx":2,"val":"Square"},{"idx":3,"val":"Circle"},{"idx":4,"val":"Oval"},{"idx":5,"val":"Egg"}]},
{"range":"Color","values":[{"idx":0,"val":"Red"},{"idx":1,"val":"Blue"},{"idx":2,"val":"Yellow"},{"idx":3,"val":"Green"},{"idx":4,"val":"Cyan"}]}
]"
In a next step the index of an ordinal value has to be found in this object. The function should find the index of the value 'Blue' in the range 'Color'.
So the function should have the meta scripting form
f("Color")("Blue")=1
What is the most elegant form to create such a function in the context of D3 and javascript?
Depending on your use case, it might make sense to convert the data structure to a different structure more suitable for direct access. E.g. you could convert your structure to
var data = {
Shape: ['Random', 'Line', ...],
// ...
};
and access it with
data['Shape'].indexOf('Line') // or data.Shape.indexOf('Line')
Or go even one step further and convert to
var data = {
Shape: {
Random: 0,
Line: 1,
// ...
},
// ...
};
and access it with
data['Shape']['Line'] // or data.Shape.Line
What the best solution is depends on the actual use case.
Converting the structure dynamically is pretty straight forward. Here is an example to convert it to the first suggestion:
var newData = {};
data.forEach(function(item) {
newData[item.range] =
item.values.map(function(value) { return value.val; });
});
This would also reduce redundancy (e.g. idx seems to correspond with the element index).
Would this work for you ?
var dataJson = '[ \
{"range":"Shape","values":[{"idx":0,"val":"Random"},{"idx":1,"val":"Line"},{"idx":2,"val":"Square"},{"idx":3,"val":"Circle"},{"idx":4,"val":"Oval"},{"idx":5,"val":"Egg"}]},\
{"range":"Color","values":[{"idx":0,"val":"Red"},{"idx":1,"val":"Blue"},{"idx":2,"val":"Yellow"},{"idx":3,"val":"Green"},{"idx":4,"val":"Cyan"}]}\
]';
var data = JSON.parse(dataJson);
for (each in data){
if ( (data[each].range) === 'Color'){
for (eachVal in data[each].values){
if (data[each].values[eachVal].val === 'Blue'){
alert(data[each].values[eachVal].idx);
}
}
} ;
}
And here is the JSFiddle for you too.

Categories

Resources