In Mustache templating is there an elegant way of expressing a comma separated list without the trailing comma?

后端 未结 17 1542
滥情空心
滥情空心 2020-12-02 10:26

I am using the Mustache templating library and trying to generate a comma separated list without a trailing comma, e.g.

red, green, blue

相关标签:
17条回答
  • 2020-12-02 10:50

    For JSON data I suggest:

    Mustache.render(template, settings).replace(/,(?=\s*[}\]])/mig,'');

    The regexp will remove any , left hanging after the last properties.

    This will also remove , from string values contining ", }" or ", ]" so make sure you know what data will be put into your JSON

    0 讨论(0)
  • 2020-12-02 10:51

    I'm using custom functions for that, in my case when working with dynamic SQL queries.

        $(document).ready(function () {
        var output = $("#output");    
        var template = $("#test1").html();
        var idx = 0;
        var rows_count = 0;
        var data = {};
        
        data.columns = ["name", "lastname", "email"];
        data.rows  = [
          ["John", "Wick", "john.wick@hotmail.com"],
          ["Donald", "Duck", "donald.duck@ducks.com"],
          ["Anonymous", "Anonymous","jack.kowalski@gmail.com"]
        ];
    
        data.rows_lines = function() {
          let rows = this.rows;
          let rows_new = [];
          for (let i = 0; i < rows.length; i++) {
            let row = rows[i].map(function(v) {
                return `'${v}'`
            })
            rows_new.push([row.join(",")]);
          }
          rows_count = rows_new.length;
          return rows_new
        }
    
        data.last = function() {
            return idx++ === rows_count-1; // omit comma for last record
        }
        
        var html = Mustache.render(template, data);
        output.append(html);
    
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/4.0.1/mustache.min.js"></script>
    <h2>Mustache example: Generate SQL query (last item support - omit comma for last insert)</h2>
    
    <div id="output"></div>
    
    <script type="text/html" id="test1">
        INSERT INTO Customers({{{columns}}})<br/>
        VALUES<br/>
          {{#rows_lines}}
             ({{{.}}}){{^last}},{{/last}}<br/>
          {{/rows_lines}}
    </script>

    https://jsfiddle.net/tmdoit/4p5duw70/8/

    0 讨论(0)
  • 2020-12-02 10:52

    Simplest way I found was to render list and then remove last char.

    1. Render mustache.
    2. Remove any white space before and after string.
    3. Then remove last character

      let renderedData = Mustache Render(dataToRender, data); renderedData=(renderedData.trim()).substring(0, renderedData.length-1)

    0 讨论(0)
  • If you are using java, you can use the following :

    https://github.com/spullara/mustache.java/blob/master/compiler/src/test/java/com/github/mustachejava/util/DecoratedCollectionTest.java

    MustacheFactory mf = new DefaultMustacheFactory();
    Mustache test = mf.compile(new StringReader("{{#test}}{{#first}}[{{/first}}{{^first}}, {{/first}}\"{{value}}\"{{#last}}]{{/last}}{{/test}}"), "test");
    StringWriter sw = new StringWriter();
    test.execute(sw, new Object() {
        Collection test = new DecoratedCollection(Arrays.asList("one", "two", "three"));
    }).flush();
    System.out.println(sw.toString());
    
    0 讨论(0)
  • 2020-12-02 10:56

    In more complex scenarios, a view model is desirable for lots of reasons. It represents the model's data in a manner that is better suited for display or, in this case, template processing.

    In case you are using a view model, you can easily represent lists in a way that facilitates your goal.

    Model:

    {
        name: "Richard",
        numbers: [1, 2, 3]
    }
    

    View Model:

    {
        name: "Richard",
        numbers: [
            { first: true, last: false, value: 1 },
            { first: false, last: false, value: 2 },
            { first: false, last: true, value: 3 }
        ]
    }
    

    The second list represention is horrible to type but extremely straightforward to create from code. While mapping your model to the view model, just replace every list you need first and last for with this representation.

    function annotatedList(values) {
        let result = []
        for (let index = 0; index < values.length; ++index) {
            result.push({
                first: index == 0,
                last: index == values.length - 1,
                value: values[index]
            })
        }
        return result
    }
    

    In case of unbounded lists, you can also only set first and omit last, as one of them is sufficient for avoiding the trailing comma.

    Using first:

    {{#numbers}}{{^first}}, {{/first}}{{value}}{{/numbers}}
    

    Using last:

    {{#numbers}}{{value}}{{^last}}, {{/last}}{{/numbers}}
    
    0 讨论(0)
  • Interesting. I know it's kind of lazy but I usually get around this by templating in the value assignment rather than trying to comma delimitate the values.

    var global.items = {};
    {{#items}}
        global.items.{{item_name}} = {{item_value}};
    {{/items}}
    
    0 讨论(0)
提交回复
热议问题