ebody: String mit Variable festlegen, um diesen später in einer arr.map() Funktion zu verwenden

problematische Seite

Hallo,

wie kann ich einen String mit Variable festlegen, um diesen später in einer arr.map() Funktion zu verwenden?

const arrFruits = ['Apple','Banana','Orange'];

const str = `<li>\${item}</li>`;

arrList = arrFruits.map(item => eval(str));

arrList = `<ul>${arrList.join('')}</ul>`;

console.log(arrList);

Das ist nur ein kurzes Beispiel, was sich nur auf diese Frage bezieht. Mir ist bewusst, dass ich den Wert von str auch direkt in map(...) ohne \$, mit $ einbinden könnte z.B. Aber mich würde interessieren, wie man str in map() einbinden kann, so dass item als Variable gilt.

Gruß ebody

  1. problematische Seite

    Tach!

    wie kann ich einen String mit Variable festlegen, um diesen später in einer arr.map() Funktion zu verwenden?

    Das ist so nicht direkt vorgesehen. In Backticks werden Template-Literale definiert. Die werden - wie jedes andere Literal auch - sofort an Ort und Stelle berechnet. Wenn du das nicht an der Stelle haben möchtest, darfst du das nicht als Template-Literal notieren, sondern als ganz normalen String. Wenn du unbedingt eval() verwenden willst, musst du dann einen syntaktisch korrekten String zurechtbauen. Aber dann kannst du auch gleich den gewünschten String direkt und ohne eval() zusammenstellen.

    Es gibt aber Tagged Templates. Dabei gibt man eine Funktion an, die das Literal auflöst. Diese kann man gemäß dem zweiten Beispiel der verlinkten Stelle auch so schreiben, dass sie nicht den berechneten String direkt zurückgibt, sondern eine Funktion, die man später mit Parametern aufrufen kann.

    dedlfix.

  2. problematische Seite

    Ich bin etwas zu müde um herauszufinden, was Du da willst.

    Aber das augenscheinliche Problem würde ich - statt mit vielen „Bockstürzen“ - ganz billig stumpf so lösen:

    const arrFruits = ['Apple','Banana','Orange'];
    
    arrList = '<ul><li>' + arrFruits.join('</li><li>') + '<li></ul>';
    
    console.log(arrList);
    

    Dazu ggf. noch eine Abfrage, ob arrFruits vielleicht leer ist.

    Wenn jetzt ul und li austauschbar sein sollen sehen ich kein wirkliches Hindernis für stumpfe Stringoperationen.

  3. problematische Seite

    Hallo ebody,

    oh weh, das geht tatsächlich.

    Aber nicht ganz so wie Du es machst.

    const str = `<li>${item}</li>`;
    

    wertet ${item} an Ort und Stelle aus. Das willst Du nicht. Die Idee, das Template erstmal zu speichern und es dann zum passenden Zeitpunkt mit eval auszuwerten, ist aber möglich - du musst das Template dazu in einem String "verstecken". Das geht so:

    const str = "`<li>${item}</li>`";
    const arr = [ "a", "b", "c" ];
    let list = array.map(item => eval(str));
    

    Also - ja, geht. Ist aber ineffizient. JavaScript muss nun (vermutlich) für jeden Callback das Template neu compilieren. Wenn Du den Callback nicht gleich in array.map notieren willst, dann speichere nicht das Template, sondern die ganze Callback-Funktion in einer Variablen:

    const makeItem = item => `<li>${item}</li>`;
    const arr = [ "a", "b", "c" ];
    let list = array.map(makeItem);
    

    Das Problem der von Dedlfix genannten tagged templates ist zum einen, dass man Tag und Template nicht trennen kann. Du kannst nicht das Template in eine Variable legen und dann später Funktion und Template zusammenbringen. Zum anderen wird auch bei einem tagged template das Template in dem Moment ausgewertet, wo Du es zuweist. Du müsstest also eine Dummy-Variable item bereitstellen, damit die Idee eines Funktionsgenerators gelingt, oder in die geschweiften Klammern Zahlen setzen (für: erster Parameter, zweiter Parameter, etc)…

    Für

    const makeItem = funcTemplate`<li>${0}</li>`;
    

    könnte man eine Funktion funcTemplate schreiben, die ihren ersten übergebenen Parameter zwischen die konstanten Bestandteile setzt. Aber ist das besser? Eher nicht.

    Wenn Du rein akademische Übungen betreibst, bringt eine Rückfrage nun weiter nichts. Aber wenn Du ein konkretes Problem hast, das Du mit diesem Konstrukt lösen willst, dann solltest Du Dir auf jeden Fall noch die Raketenidee anschauen. Oder erzählen, was genau Du vorhast und welche Rahmenbedingungen zu beachten sind. Dann kann man vielleicht eine günstigere Lösung vorschlagen.

    Rolf

    --
    sumpsi - posui - obstruxi