How can I add superscripts and subscript in a string? - javascript

I have an array of objects containing lots of data or objects which I import and display in a webpage.
const arr = [
{
question: "What is molecular formula for water?",
options: ["H2O","CO2","H2O","H2O"]
}
]
So Is it possible to write superscript and subscript in a string? To make the numbers superscipted or subscripted while displaying in a webpage.
Note: I have array of around 1000 objects from which only 100 of them are displayed. Some of them may contain superscript whereas some of them may not. Isn't there any simpler way like using alt codes for super scripts and subscripts so that I can directly put it in string.

You could map your array of options to a formatted version of that option by using .replace() to wrap each number in <sup></sup> tags to make it appear as subscript text like so:
const arr = [
{
question: "What is molecular formula for water?",
options: ["H2O","CO2","H2O","H2O"]
}
]
const formatted = arr[0].options.map(elem => elem.replace(/(\d)/g, `<sub>$1</sub>`));
console.log(formatted);
document.body.innerHTML = formatted;

Regex free approach. Supports hydrated salts (like blue vitorl) and balancing numbers. To add hydrated salts, just add a dot
const arr = [{
question: "What is molecular formula for water?",
options: ["H2O", "CO2", "H2O", "H2O"]
},
{
question: "What is the molecular formula for Copper(II) sulphate?",
options: ["H2O", "(CuSO4).5H2O", "H2O2", "D2O"]
}
]
arr.forEach(obj => { // map the first array
let answer = obj["options"].map((options) => { // map all the answers
let op = options.split('').map((data, i) => { // split all the answer strings
if (!isNaN(data)) { // if the data is a number the add <sub> tags to it
if (options.split('')[i - 1] != "." && i != 0) { // if i = 0 is a number then it is a blancing number. Then don't add <sub> tags to it
// also check if the previous string is a dot. Means that has water of crystillization or any other extension
let str = "<sub>" + data + "</sub>"
return str
}else{
return data
}
} else {
return data // else return the string
}
})
return op.join("") // join the string
})
// logic to add data display it
let question = document.createElement("h1") // question
question.innerHTML = obj["question"] // append question content
document.body.appendChild(question) // append the question element to body
let ul = document.createElement("ul") // create unsorted list
answer.forEach((things) => { // for each of the answers
let ali = document.createElement("li") // create a li
ali.innerHTML = things // add answers to the lu
ul.appendChild(ali) // append the li to the ul
})
document.body.appendChild(ul) // append the ul to the body
})
We are just splitting your answers and checking if the data is a number. If it is then we add <sub> tags to it.
To display them, we create elements dynamically and in a loop, we add compounds to a li and then append that to a ul
Make sure to follow the basic chem rules while formatting compounds

Generic example for replacing digits in all values with unicode subscript digits :
var json = JSON.stringify( [ { question: "What is molecular formula for water?", options: ["H2O","CO2","H2O","H2O"] } ] )
var arr = JSON.parse(json, (k, v) => v.trim ? v.replace(/\d/, m => '₀₁₂₃₄₅₆₇₈₉'[m]) : v)
console.log(arr)
document.body.textContent = arr[0].options

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

HTML code generation from string using Javascript

I am developing a javascript tool that will extract the string, obtain relevant strings and create html tags.
const string = "Create heading 1 that will have class abc and id xyz";
const elementList = [
{name: 'heading 1', tag: 'h1'},
{name: 'heading 2', tag: 'h2'}
{name: 'paragraph', tag: 'p'},
];
function convertTag(input) {
return elementList.reduce((acc, a) => {
const re = new RegExp(a.name,"g");
return acc.replace(re, a.tag);
}, input);
}
let initialString = convertTag(string)
//returns create h1 that will have class abc and id xyz
let htmlElement = initialString. split (" ")[1]; // will return h1
let code = `<${htmlElement}> </${htmlElement}>`;
How do I include class and Id? There
might be other attributes like alt, src etc. Is there any library to grab the HTML attributes?
Thank you
The result of running the following code is abc xy being printed in the console.
The idea is to search for the prefix "class " and "id " then grab 1 or more alphanumeric characters, bunch em together and return them. The match function returns a bunch of things, including the position within the string. Since we're just interested in the 1st (only!) result, we can grab element 0 from the result, treating it like a simple array.
The half-awake will note that these simple regexes would allow number to start the following group. Rather than grabbing 1 or more alphanumerics, I suppose a more robust solution would be to grab 1 alpha AND 0 or more alphanumerics.
Someone put me onto Expresso as a useful (free) tool to play around with regexes on the desktop.
function test1()
{
const s = 'Create heading 1 that will have class abc and id xy';
let cl = s.match(/(?<=class )\w+/)[0];
let id = s.match(/(?<=id )\w+/)[0];
console.log(cl,id);
}

Splitting a string for CSV formatting

I have a string that I've formed based on certain data. It contains a list of comma separated values.
I run this string through a function which allows me to separate these values so that I can show them appropriately in the HTML.
This works fine. However there's one error I'm unable to resolve. One of the returned values is from a HTML textfield which means the user can write on multiple different lines. As a result, the function I use to split up my values is splitting up the textfield values into multiple lines.
I've consoled logged my string before it hits the function. As you can see, the comments appear fine in the quotations with a space in between.
20,Order,Item,Title,,Assignee,Comments,Image Path,Timestamp,Due Date,Completed
21,0,1,"Issue 1",,"","I have some comments that are
going here on multiple lines",,"2019/11/28, 12:20:55","",""
The function
csvToJSON(csv) {
const lines: string[] = csv
// escape everything inside quotes to NOT remove the comma there
.replace(/"(.*?)"/gm, (item) => encodeURIComponent(item))
.split('\n');
lines.pop();
// separate the headers from the other lines and split them
const headers: string[] = lines.shift().split(',');
// should contain all CSV lines parsed for the html table
const data: any[] = lines.map((lineString, index) => {
const lineObj = {};
const lineValues = lineString.split(',');
headers.forEach((valueName, index) => {
// remove trailing spaces and quotes
if (lineValues[index] != undefined) {
lineObj[valueName] = lineValues[index].replace(/%22(.*?)%22/gm, (item) => decodeURIComponent(item)).trim();
}
});
return lineObj; // return lineObj for objects.
});
console.log('csvToJSON - data = ', data);
return { data, headers };
}
In the above function, you can see a console log at the end to log the final converted data.
This ends up resulting in the following:
0: {20: "21", Order: "0", Item: "1", Title: ""Issue 1"", "": "", Assignee: """", …}
1: {20: ""}
2: {20: "going here on multiple lines",,"2019/11/28", Order: "12:20:55","","""}
As you can see, my comments have been a bit butchered.
Is there a way to resolve this so that everything else is separated correctly, but my comments text (which can have multiple lines) isn't broken up?
try this method
function CSVtoArray(text) {
var re_valid = /^\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*(?:,\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*)*$/;
var re_value = /(?!\s*$)\s*(?:'([^'\\]*(?:\\[\S\s][^'\\]*)*)'|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*))\s*(?:,|$)/g;
if (!re_valid.test(text)) return null;
var a = [];
text.replace(re_value,
function(m0, m1, m2, m3) {
if (m1 !== undefined) a.push(m1.split("|");
else if (m2 !== undefined) a.push(m2.split(","));
else if (m3 !== undefined) a.push(m3);
return '';
});
if (/,\s*$/.test(text)) a.push('');
return a;
};

Efficient way to search within multiple values in json

I have multiple records like this,
name: John Doe aliases: John, Doe, JD unique_id: 1 ...
My question is how do I search efficiently within the aliases & full name.
If the search query is any of those 4 (John Doe, John, Doe, JD) I would like to find the unique id (in this case 1).
What I have done: I have a very straightforward implementation that loops through the entire data until it finds. It takes a long time since the number of fields is very high.
Note: I am using javascript if it helps. Also I have the permission to change the data format (permanently), if it will make the search more efficient. Most of the search queries tend to be one of the aliases rather than full name.
Sample Code: https://jsfiddle.net/nh7yqafh/
function SearchJSON(json, query) {
var champs = json.champs;
for (var i = 0; i < champs.length; ++i) {
if (query == champs[i].name)
return champs[i].unique_id;
for (var j = 0; j < champs[i].aliases.length; ++j) {
if (query == champs[i].aliases[j])
return champs[i].unique_id;
}
}
}
//Data format is similar to what vivick said
var json_string = '{"count":5,"champs":[{"name":"Abomination","aliases":["abomination","AB","ABO"],"unique_id":1},{"name":"Black Bolt","aliases":["blackbolt","BB","BBT"],"unique_id":2},{"name":"Black Panther","aliases":["blackpanther","BP","BPR"],"unique_id":3},{"name":"Captain America","aliases":["captainamerica","CA","CAP"],"unique_id":4}]}'
var json = JSON.parse(json_string);
query="CA";
alert( "id of "+query+" is "+SearchJSON(json, query));
I guess you have a structure similar to the following one :
[
{
"name": "xxx",
"aliases": ["x", "xx", "xxx"],
"unique_id": 1,
/* [...] */
},
/* [...] */
]
You can then do something like this :
const queryParam = /*search query*/;
const arr = /* get the JSON record */;
const IDs = arr
.filter( entry =>(entry.aliases.includes(queryParam) || queryParam===entry.name) )
.map(entry=>entry.uniqueId);
This will give you an array of IDs which are potential matches.
If you need either 0 or 1 result only :
const ID = IDs[0] || null;
This will simply retrieve the first matched ID if there's one, otherwise it will set ID to null.
NB:
If you use an object of objects instead of an array of object, there's just a little bit of modifications to do (mainly using Object.entries) but it still is trivial.
PS:
I would recommend to always add the full name in the aliases, this will ease the filtering part (no || would be required).

Converting plain text data to json

I have some data that I am trying to process with javascript.
DATA:
A. Category one
1. item one
2. item two
B. Category two
3. item three
4. item four
C. Category three
5. item five
6. item six
DESIRED OUTPUT:
[{
"Category one":["item one", "item two"],
"Category two":["item three", "item four"],
"Category three":["item five", "item six"]
}]
Is there a library that will help me with text parsing in javascript?
THIS IS AS FAR AS I GOT:
function parseFormat(str) {
var arr = [];
str.split('\n').forEach(function (line) {
var obj = {};
line.split('.').forEach(function (item) {
if (isNaN(item)) {
// ??
} else {
}
});
return ?;
});
}
Help? Thanks
Here is the complete function. Please have a look at the code below.
Function to parse the string
function parseFormat(strArg) {
var
category,
output = {}, // Output
str = strArg.trim(); // Remove unwanted space before processing
str.split('\n').forEach(function(line) {
var item = line.split('.');
if (item[0].match(/\d/)) { // Match a decimal number
// Remove unwanted space & push
output[category].push(item[1].trim());
} else if (item[0].match(/\D/)) { // Match UPPERCASE alphabet
// Remove unwanted space
category = item[1].trim();
output[category] = []
}
});
return output;
}
Input string
// ES6 Template Strings to define multiline string
var str = `
A. Category one
1. item one
2. item two
B. Category two
3. item three
4. item four
C. Category three
5. item five
6. item six
`;
Function call
// Final output Array
var finalOutput = [];
// Parse input string
var parseStr = parseFormat(str);
finalOutput.push(parseStr);
// Desired JSON output
console.log(JSON.stringify(finalOutput));
You can look at the Browser Console for the desired JSON output.
Hope it helps!
This is a simple way to get the information out of the file format and into some variables. It isn't a complete solution. Though once you get the information into variables you can figure out how to json it.
var category;
var items;
var item = line.split('.'); //Don't use the forEach on the line split.
if (item[0].match(/\d/) ) {
// match a decimal number
items = item[1];
} else if (item[0].match(/\D/) ) {
//match a letter
category = item[1];
}

Categories

Resources