-2
var AcceptLngs = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pt-BR'],
    _getI18N = { 
        'wordToTranslate' : {
            'pt' : `translatedWord`,
            [...]
        },
        '2ndWordToTranslate' : {
            'pt-BR' : `translatedWord`,
            [...]
         }
    },
    nav = window.navigator,
    navLng = nav.language || nav.browserLanguage || nav.userLanguage,
    prefs = nav.languages,
    navPrefLng = prefs[0],
    defaultLng = 'en',
    lng = navLng, //It must be set for translation

    // CHECK THE LANGUAGE OF THE NAVIGATOR.
    checkLng = function checkLng() {
        // isL10nAvailable:
        if (AcceptLngs.indexOf(navPrefLng) < -1) {
            lng = navPrefLng;
            return lng;
        }
    },
    // SEARCH IF LANGUAGE OF THE APP IS AVAILABLE.
    isLngDispo = function isLngDispo() {
        // isSubstrL10nAvailable:
        checkLng();
        if (AcceptLngs.indexOf(navPrefLng) === -1) {
            lng = navPrefLng.substring(0,2);
            return lng;
        }
    },
    // SEARCH IF LANGUAGE OF THE APP IS AVAILABLE.
    setLng = function setLng() {
        // isL10nNoAvailable:
        isLngDispo();
        if (AcceptLngs.indexOf(lng) === -1) {
            lng = defaultLng;
            return lng;
        }
    };
    // APPLYING LANGUAGE FOR THE APP.
    setLng();

I am beginner in JavaScript. My script works. The problem is its execution time. I go from 102 ms (without the translation) to 448 ms (with).

I have try with loop, but I didn't manage to make it work properly. He didn't detect the language in AcceptedLng and automatically put me the nav.language.

Perhaps, more simply, I should search directly in '_getI18N', but I have not yet gotten familiar with the search in the arrays, and I can not get any results either.

Info: To translate, I use _getI18N[wordToTranslate][lng] into my script.

halfer
  • 19,824
  • 17
  • 99
  • 186
K-mikaZ
  • 1
  • 1
  • 2
    Have you tried debugging what part of the code consumes how much time to narrow down your problem further? – Zim84 Mar 18 '18 at 10:25
  • The problem seems to come (apparently) that setLng () calls a function that itself calls another function. My tests with the loops did not take so much time, but only returned to me `nav.langue`. My attempts to search for arrays did not take me too long, but only returned to `defaultLng` (that is` en`). But I'm a noob. – K-mikaZ Mar 18 '18 at 10:43
  • `arr.indexOf` is _O(n)_, `obj[foo]` is _O(1)_ – Paul S. Mar 18 '18 at 10:44
  • Correction: I had other scripts called on the same site. After disabling them, I go to 172ms (less alarming). I just saw that I can further reduce by: // isL10nAvailable: if (AcceptLngs.indexOf(navPrefLng) < -1) { lng = navPrefLng; return lng; } else { lng = navPrefLng.substring(0,2); return lng; } @Paul S. : I test that. – K-mikaZ Mar 18 '18 at 11:03
  • Ok, I have test with @Paul S. suggestions and reduce my code by deleting a function (and replacing it with else :) ). I return to the initial lead time. I mark the subject [solved] by editing the title of my post. Thanks for your according time. – K-mikaZ Mar 18 '18 at 11:22

1 Answers1

1

With your data structure you could do something like this..

const acceptedLanguages = ['de', 'en', 'es', 'fr', 'it', 'pt'];
const _getI18N = { 
    'x': {
        'en': 'color',
        'en-GB': 'colour'
    },
    'y': {
        'en': 'hello',
        'en-US': 'howdy'
     },
     'z': {}
};

Figure out and record a common known language between client and _getI18N dictionary (based on acceptedLanguages)

const nav = window.navigator;
const clientLanguages = [
    nav.language || nav.browserLanguage || nav.userLanguage,
    ...window.navigator.languages,
    'en'
].filter(Boolean);

const getRoot = lang => lang.split('-')[0];

const langRootIncludes = lang => {
    const root = getRoot(lang);
    return acceptedLanguages.includes(root);
};

const candidateLanguage = clientLanguages.find(
    lang => langRootIncludes(lang)
);
const candidateLanguageRoot = getRoot(candidateLanguage);

So translating to the common known language would look something like

const translate = word => {
    const dict = _getI18N[word];
    if (!dict) return word;

    return dict[candidateLanguage] // e.g. first try pt-BR
        || dict[candidateLanguageRoot] // then fall back to pt
        || word; // then fall back to input
};

Then

candidateLanguage; // "en-US"
candidateLanguageRoot; // "en"

translate('x'); // "color", fell back to en
translate('y'); // "howdy", found en-US
translate('z'); // "z", fell back to input (no lang entry)
translate('foo'); // "foo", fell back to input (no entry at all)
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • I test, and work it's work like a charm (98ms). BIG Thks – K-mikaZ Mar 18 '18 at 12:44
  • I have just modified `const clientLanguages[(allContent) + " "].filter(Boolean);` explain here https://stackoverflow.com/questions/10145946/what-is-causing-the-error-string-split-is-not-a-function#answer-10145979 to suppress `TypeError: lang.split is not a function` – K-mikaZ Mar 18 '18 at 13:13