Home > Blockchain >  JavaScript: How to parse and then render a collection of dictionary entries? (arrays, key-value, sor
JavaScript: How to parse and then render a collection of dictionary entries? (arrays, key-value, sor

Time:03-30

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>");
  • Related