add sort function

This commit is contained in:
pantor
2018-02-18 19:41:56 +01:00
parent 37d16d3c3a
commit 9f97c9add1
3 changed files with 25 additions and 5 deletions

View File

@@ -99,12 +99,12 @@ Variables are rendered within the `{{ ... }}` expressions.
```c++
json data;
data["neighbour"] = "Peter";
data["guests"] = {"Jeff", "Patrick", "Tom"};
data["guests"] = {"Jeff", "Tom", "Patrick"};
data["time"]["start"] = 16;
data["time"]["end"] = 22;
// Indexing in array
render("{{ guests/1 }}", data); // "Patrick"
render("{{ guests/1 }}", data); // "Tom"
// Objects
render("{{ time/start }} to {{ time/end }}pm"); // "16 to 22pm"
@@ -127,8 +127,8 @@ render(R"(Guest List:
/* Guest List:
1: Jeff
2: Pierre
3: Tom */
2: Tom
3: Patrick */
```
In a loop, the special variables `index (number)`, `index1 (number)`, `is_first (boolean)` and `is_last (boolean)` are available. You can also iterate over objects like `{% for key, value in time %}`.
@@ -172,7 +172,12 @@ render("I count {{ length(guests) }} guests.", data); // "I count 3 guests."
// Get first and last element in a list
render("{{ first(guests) }} was first.", data); // "Jeff was first."
render("{{ last(guests) }} was last.", data); // "Tom was last."
render("{{ last(guests) }} was last.", data); // "Patir was last."
// Sort a list
render("{{ sort([3,2,1]) }}", data); // "[1,2,3]"
render("{{ sort(guests) }}", data); // "[\"Jeff\", \"Patrick\", \"Tom\"]"
// Round numbers to a given precision
render("{{ round(3.1415, 0) }}", data); // 3

View File

@@ -12,6 +12,8 @@
#include <iostream>
#include <locale>
#include <regex>
#include <vector>
#include <algorithm>
#include <type_traits>
@@ -242,6 +244,7 @@ struct Parsed {
Lower,
Range,
Length,
Sort,
First,
Last,
Round,
@@ -372,6 +375,11 @@ public:
const std::vector<json> list = eval_expression<std::vector<json>>(element.args[0], data);
return list.size();
}
case Parsed::Function::Sort: {
std::vector<json> list = eval_expression<std::vector<json>>(element.args[0], data);
std::sort(list.begin(), list.end());
return list;
}
case Parsed::Function::First: {
const std::vector<json> list = eval_expression<std::vector<json>>(element.args[0], data);
return list.front();
@@ -605,6 +613,7 @@ public:
{Parsed::Function::Lower, function_regex("lower", 1)},
{Parsed::Function::Range, function_regex("range", 1)},
{Parsed::Function::Length, function_regex("length", 1)},
{Parsed::Function::Sort, function_regex("sort", 1)},
{Parsed::Function::First, function_regex("first", 1)},
{Parsed::Function::Last, function_regex("last", 1)},
{Parsed::Function::Round, function_regex("round", 2)},

View File

@@ -107,6 +107,12 @@ TEST_CASE("functions") {
// CHECK_THROWS_WITH( env.render("{{ length(5) }}", data), "[json.exception.type_error.302] type must be array, but is number" );
}
SECTION("sort") {
CHECK( env.render("{{ sort([3, 2, 1]) }}", data) == "[1,2,3]" );
CHECK( env.render("{{ sort([\"bob\", \"charlie\", \"alice\"]) }}", data) == "[\"alice\",\"bob\",\"charlie\"]" );
// CHECK_THROWS_WITH( env.render("{{ sort(5) }}", data), "[json.exception.type_error.302] type must be array, but is number" );
}
SECTION("first") {
CHECK( env.render("{{ first(names) }}", data) == "Jeff" );
// CHECK_THROWS_WITH( env.render("{{ length(5) }}", data), "[json.exception.type_error.302] type must be array, but is number" );