I want to display a list of dictionary entries in a table using javascript, using some combination of arrays and key/value pairs.
Here is what I've got to work so far:
let d = new Map();
d.set('stack', '[n] 1. an orderly pile 2. a list in which the next item to be removed is the most recently stored [v] 1. to arrange in order 2. to arrange in stacks')
d.set('overflow', '[n] 1. a large flow 2. the occurrence of surplus liquid')
;
document.write("<table>");
for (const [key, value] of d.entries()) {
document.write("<tr><td class=\"word\">" key ": " "</td>" "<td class=\"def\">" value "</td>\n");
}
document.write("</table>");
table {
border: solid thin;
border-collapse: collapse;
}
td, th {
border-collapse: collapse;
border: 1.5px solid #aaa;
padding: 4px 6px;
}
td.word {
background-color: #cee5ec;
vertical-align: top;
border-right-width: 0px;
}
td.def {
background-color: #eee;
border-left-width: 0px;
}
Which looks okay, but it would be better (easier to type a large number of entries, and language-agnostic) if I could prepare all entries as a string literal and have the script parse and reorganize it:
let d = new Map();
let ddata = (`
stack: [n] 1. an orderly pile 2. a list in which the next item to be removed is the most recently stored [v] 1. to arrange in order 2. to arrange in stacks
overflow: [n] 1. a large flow 2. the occurrence of surplus liquid
`).split('\n');
for (let i = 0; i < ddata.length; i ) {
ddata[i].split(': ');
d.set(ddata[i][0]), d.set(ddata[i][1]);
}
document.write("<table>");
for (const [key, value] of d.entries()) {
document.write("<tr><td class=\"word\">" key ": " "</td>" "<td class=\"def\">" value "</td>\n");
}
document.write("</table>");
table {
border: solid thin;
border-collapse: collapse;
}
td, th {
border-collapse: collapse;
border: 1px solid #aaa;
padding: 4px 6px;
}
td.word {
background-color: #cee5ec;
vertical-align: top;
border-right-width: 0px;
}
td.def {
background-color: #eee;
border-left-width: 0px;
}
Performance in the browser is not really a concern at this point, as the end result will not be for a general audience. If performance does ever become a concern, I will serve the dictionary in sections.
The bigger issue right now is that the following code is not working as expected at all. Instead of splitting the string at the :
, it's making arrays of individual letters:
ddata[i].split(': ');
d.set(ddata[i][0]), d.set(ddata[i][1]);
Ideally, I would like to create breakpoints at the part-of-speech symbol (noun, verb, etc). I know this can be done with regex like (\[\w*\])
to match [n]
or [noun]
. And then each numbered meaning after than could be separated using \d.
to match 1.
2.
and so on.
Here is a rough static HTML example of the desired end result:
table {
border: solid thin;
border-collapse: collapse;
}
td, th {
border-collapse: collapse;
border: 1px solid #aaa;
padding: 4px 6px;
}
td.word {
background-color: #cee5ec;
vertical-align: top;
border-right-width: 0px;
}
td.def {
background-color: #eee;
border-left-width: 0px;
}
.pos {
font-weight: bold;
}
.num {
display: inline-block;
background-color: #fff;
border-radius: 16px;
padding: 1px 0px 0px 4px;
width: 15px;
height: 18px;
font-family: sans-serif;
color: #555;
font-size: 14px;
font-weight: 200;
border: 1px solid #ccc;
}
<table>
<tr>
<td >stack:</td><td ><span >[n]</span> <span >1.</span> an orderly pile <span >2.</span> a list in which the next item to be removed is the most recently stored</br><span >[v]</span> <span >1.</span> to arrange in order <span >2.</span> to arrange in stacks</td>
</tr>
<tr>
<td >overflow:</td><td ><span >[n]</span> <span >1.</span> a large flow <span >2.</span> the occurrence of surplus liquid</td>
</tr>
</table>
↑ Note the </br>
in between [n]
and [v]
categories, the <span>
tags wrapping [n]
and 1.
(with classes pos
and num
respectively).
Putting it all together is turning into a long process of trial and error. Any help is appreciated.
CodePudding user response:
.split
on a string creates a new array, it does not change anything "in place".
You have to store the results:
const [ key, value ] = ddata[i].split(': ');
d.set(key, value);
You also might want to filter out empty lines:
("...").split('\n').filter(s => s.length);
Also note that your new approach only works if your value strings do not contain ": "
. If you want to ensure only the first ": "
is used to split between key and value, you could do something like this:
const [ key, ...values ] = ddata[i].split(": ");
d.set(key, values.join(": "));
let d = new Map();
let ddata = (`
stack: [n] 1. an orderly pile 2. a list in which the next item to be removed is the most recently stored [v] 1. to arrange in order 2. to arrange in stacks
overflow: [n] 1. a large flow 2. the occurrence of surplus liquid
`).split('\n').filter(s => s.length);
for (let i = 0; i < ddata.length; i ) {
const [ key, value ] = ddata[i].split(': ');
d.set(key, value);
}
document.write("<table>");
for (const [key, value] of d.entries()) {
document.write("<tr><td class=\"word\">" key ": " "</td>" "<td class=\"def\">" value "</td>\n");
}
document.write("</table>");
table {
border: solid thin;
border-collapse: collapse;
}
td, th {
border-collapse: collapse;
border: 1px solid #aaa;
padding: 4px 6px;
}
td.word {
background-color: #cee5ec;
vertical-align: top;
border-right-width: 0px;
}
td.def {
background-color: #eee;
border-left-width: 0px;
}
CodePudding user response:
For yours, when you spit at "/n" it had lines that were empty so you would need to filter those out. This is what I came up with:
let d = new Map();
let ddata = `
stack: [n] 1. an orderly pile 2. a list in which the next item to be removed is the most recently stored [v] 1. to arrange in order 2. to arrange in stacks
overflow: [n] 1. a large flow 2. the occurrence of surplus liquid
`.split('\n') // Spits at newline
.filter(ddata => ddata.length > 0) // Filters every line that is empty
.map(ddata => ddata.split(':')) // Splits at colon
.forEach(ddata => { // For each line adds the word/key and def/value to the map
d.set(ddata[0], ddata[1].trim());
})
document.write("<table>");
for (const [key, value] of d.entries()) {
document.write("<tr><td class=\"word\">" key ": " "</td>" "<td class=\"def\">" value "</td>\n");
}
document.write("</table>");