Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions libraries/AdaptiveExpressions/BuiltinFunctions/Reverse.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Reverses the order of the elements in a String or Array.
/// </summary>
internal class Reverse : ExpressionEvaluator
{
/// <summary>
/// Initializes a new instance of the <see cref="Reverse"/> class.
/// </summary>
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<object>().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);
}
}
}
1 change: 1 addition & 0 deletions libraries/AdaptiveExpressions/ExpressionFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ private static IDictionary<string, ExpressionEvaluator> GetStandardFunctions()
new BuiltinFunctions.RemoveProperty(),
new BuiltinFunctions.Replace(),
new BuiltinFunctions.ReplaceIgnoreCase(),
new BuiltinFunctions.Reverse(),
new BuiltinFunctions.Round(),
new BuiltinFunctions.Select(),
new BuiltinFunctions.SentenceCase(),
Expand Down
1 change: 1 addition & 0 deletions libraries/AdaptiveExpressions/ExpressionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
2 changes: 2 additions & 0 deletions tests/AdaptiveExpressions.Tests/BadExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -934,6 +938,8 @@ public class ExpressionParserTests
Test("concat(['a', 'b'], ['b', 'c'], ['c', 'd'])", new List<object> { "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<object> { "llo", "h" }),
Test("reverse(createArray('h', 'e', 'l', 'l', 'o'))", new List<object> { "o", "l", "l", "e", "h" }),
Test("empty('')", true),
Test("empty('a')", false),
Test("empty(bag)", false),
Expand Down