diff --git a/libraries/AdaptiveExpressions/BuiltinFunctions/Reverse.cs b/libraries/AdaptiveExpressions/BuiltinFunctions/Reverse.cs
new file mode 100644
index 0000000000..d491cdbdb9
--- /dev/null
+++ b/libraries/AdaptiveExpressions/BuiltinFunctions/Reverse.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Collections;
+using System.Linq;
+
+namespace AdaptiveExpressions.BuiltinFunctions
+{
+ ///
+ /// Reverses the order of the elements in a String or Array.
+ ///
+ internal class Reverse : ExpressionEvaluator
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Reverse()
+ : base(ExpressionType.Reverse, Evaluator(), ReturnType.String | ReturnType.Array, Validator)
+ {
+ }
+
+ private static EvaluateExpressionDelegate Evaluator()
+ {
+ return FunctionUtils.ApplyWithError(
+ args =>
+ {
+ object result = null;
+ string error = null;
+
+ if (args[0] is string string0)
+ {
+ result = new string(string0.Reverse().ToArray());
+ }
+ else if (args[0] is IList list)
+ {
+ result = list.OfType().Reverse().ToList();
+ }
+ else
+ {
+ error = $"{args[0]} is not a string or list.";
+ }
+
+ return (result, error);
+ }, FunctionUtils.VerifyContainer);
+ }
+
+ private static void Validator(Expression expression)
+ {
+ FunctionUtils.ValidateOrder(expression, null, ReturnType.String | ReturnType.Array);
+ }
+ }
+}
diff --git a/libraries/AdaptiveExpressions/ExpressionFunctions.cs b/libraries/AdaptiveExpressions/ExpressionFunctions.cs
index 152e3c4f9d..9393ce6b3a 100644
--- a/libraries/AdaptiveExpressions/ExpressionFunctions.cs
+++ b/libraries/AdaptiveExpressions/ExpressionFunctions.cs
@@ -137,6 +137,7 @@ private static IDictionary GetStandardFunctions()
new BuiltinFunctions.RemoveProperty(),
new BuiltinFunctions.Replace(),
new BuiltinFunctions.ReplaceIgnoreCase(),
+ new BuiltinFunctions.Reverse(),
new BuiltinFunctions.Round(),
new BuiltinFunctions.Select(),
new BuiltinFunctions.SentenceCase(),
diff --git a/libraries/AdaptiveExpressions/ExpressionType.cs b/libraries/AdaptiveExpressions/ExpressionType.cs
index 3b52c2f653..849d3f2fae 100644
--- a/libraries/AdaptiveExpressions/ExpressionType.cs
+++ b/libraries/AdaptiveExpressions/ExpressionType.cs
@@ -80,6 +80,7 @@ public static class ExpressionType
public const string IndicesAndValues = "indicesAndValues";
public const string Flatten = "flatten";
public const string Unique = "unique";
+ public const string Reverse = "reverse";
// DateTime
public const string AddDays = "addDays";
diff --git a/tests/AdaptiveExpressions.Tests/BadExpressionTests.cs b/tests/AdaptiveExpressions.Tests/BadExpressionTests.cs
index fd427d5966..9270ed9377 100644
--- a/tests/AdaptiveExpressions.Tests/BadExpressionTests.cs
+++ b/tests/AdaptiveExpressions.Tests/BadExpressionTests.cs
@@ -356,6 +356,8 @@ public class BadExpressionTests
Test("contains('hello world', 'hello', 'new')"), // should have 2 parameter
Test("count(items, 1)"), // should have 1 parameter
Test("count(1)"), // first param should be list or string
+ Test("reverse(items, 1)"), // should have 1 parameter
+ Test("reverse(1)"), // first param should be list or string
Test("empty(1,2)"), // should have two params
Test("first(items,2)"), // should have 1 param
Test("last(items,2)"), // should have 1 param
diff --git a/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs b/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs
index 243ff06097..024424a0ae 100644
--- a/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs
+++ b/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs
@@ -521,6 +521,10 @@ public class ExpressionParserTests
Test("count('hello')", 5),
Test("count(\"hello\")", 5),
Test("count(concat(hello,world))", 10),
+ Test("reverse('hello')", "olleh"),
+ Test("reverse(reverse('hello'))", "hello"),
+ Test("reverse(\"hello\")", "olleh"),
+ Test("reverse(concat(hello,world))", "dlrowolleh"),
Test("replace('hello', 'l', 'k')", "hekko"),
Test("replace('hello', 'L', 'k')", "hello"),
Test("replace(nullObj, 'L', 'k')", string.Empty),
@@ -934,6 +938,8 @@ public class ExpressionParserTests
Test("concat(['a', 'b'], ['b', 'c'], ['c', 'd'])", new List { "a", "b", "b", "c", "c", "d" }),
Test("count(split(hello,'e'))", 2),
Test("count(createArray('h', 'e', 'l', 'l', 'o'))", 5),
+ Test("reverse(split(hello,'e'))", new List { "llo", "h" }),
+ Test("reverse(createArray('h', 'e', 'l', 'l', 'o'))", new List { "o", "l", "l", "e", "h" }),
Test("empty('')", true),
Test("empty('a')", false),
Test("empty(bag)", false),