I have this JSON from an API source:
"GREETINGS": [{
"TYPE_OF_GREETING": "{EVENING}",
"TEXT": "{G} {E} !!!!!"
},
{
"TYPE_OF_GREETING": "{NIGHT}",
"TEXT": "{G} {N} ... ."
}
]
From some other API (SPARQL) I can generate this "vocabulary" object:
const vocabulary = {
G: {
en: "Good",
de: "Guten",
it: "Buona"
},
E: {
en: "evening",
de: "Abend",
it: "serata"
},
N: {
en: "night",
de: "Nacht",
it: "notte"
}
};
Can you advice me the most efficient JavaScript code to get this result, please?
{
eveningGreeting: {
en: "Good evening !!!!!",
de: "Guten Abend !!!!!",
it: "Buona serata !!!!!"
},
nightGreeting: {
en: "Good night ... .",
de: "Guten Nacht ... .",
it: "Buona notte ... ."
}
}
Thank you very much for your help.
You can use reduce function to convert the translations array to an object. I also keep a list of languages to replace the templated text with the translated text.
You can try like below.
let GREETINGS = [{
"TYPE_OF_GREETING": "{MORNING}",
"TEXT": "{G} {E} !!!!!"
},
{
"TYPE_OF_GREETING": "{EVENING}",
"TEXT": "{G} {N} ... ."
}
]
const vocabulary = {
G: {
en: "Good",
ge: "Guten",
it: "Buona"
},
E: {
en: "evening",
ge: "Abend",
it: "serata"
},
N: {
en: "night",
ge: "Nacht",
it: "notte"
}
};
const output = GREETINGS.reduce((prevValue, currValue) => {
const name =
currValue.TYPE_OF_GREETING.match(/[a-z,A-Z]/g)
.join("")
.toLowerCase() + "Greeting";
const langs = ["en", "ge", "it"];
prevValue[name] = langs.reduce((prev, curr) => {
let formattedText = currValue.TEXT;
Object.entries(vocabulary).forEach(([letter, mapping]) => {
formattedText = formattedText.replace(`{${letter}}`, mapping[curr]);
});
prev[curr] = formattedText;
return prev;
}, {});
return prevValue;
}, {});
console.log(output);
NOTE: Use map, reduce, and forEach methods whenever possible.
Here is my take on it.
The languages and vocabulary are auto-detected, you could add more without changing anything in the code.
// FIRST API CONSTANT
const greetings = {
"GREETINGS": [{
"TYPE_OF_GREETING": "{MORNING}",
"TEXT": "{G} {E} !!!!!"
},
{
"TYPE_OF_GREETING": "{EVENING}",
"TEXT": "{G} {N} ... ."
}
]
};
// SECOND API CONSTANT
const vocabulary = {
G: {
en: "Good",
ge: "Guten",
it: "Buona"
},
E: {
en: "evening",
ge: "Abend",
it: "serata"
},
N: {
en: "night",
ge: "Nacht",
it: "notte"
}
};
// LIST ALL LANGUAGES
let languagesList = new Array();
for (let i in vocabulary.G) {
languagesList.push(i);
}
// CREATE NEW OBJECT
let tNewObject = {};
for (let i in greetings['GREETINGS']) {
// loops through greetings
let type = greetings['GREETINGS'][i]["TYPE_OF_GREETING"].replace(/[{}]+/g, '').toLowerCase();
let textFormat = greetings['GREETINGS'][i]["TEXT"];
let tProperty = type+'Greeting';
tNewObject[tProperty] = {};
for (let z=0;z<languagesList.length;z++) {
// loops through languages
let tValue = textFormat;
let tLanguage = languagesList[z]
for (let v in vocabulary) {
// loops through vocabulary
tValue = tValue.replace('{'+v+'}', vocabulary[v][tLanguage]);
}
tNewObject[tProperty][tLanguage] = tValue;
}
}
console.log(tNewObject);
Did you try object destructuring yet? I think it will can help you.