Skip to content

Commit

Permalink
Aggregate
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed Apr 9, 2024
1 parent f444795 commit 08b5274
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,29 @@ namespace System.Linq.Dynamic.Core.NewtonsoftJson;

public static class NewtonsoftJsonExtensions
{
#region Aggregate
/// <summary>
/// Dynamically runs an aggregate function on the <see cref="JArray"/>>.
/// </summary>
/// <param name="source">The <see cref="JArray"/>> data source.</param>
/// <param name="function">The name of the function to run. Can be Sum, Average, Min or Max.</param>
/// <param name="member">The name of the property to aggregate over.</param>
/// <returns>The value of the aggregate function run over the specified property.</returns>
public static object Aggregate(this JArray source, string function, string member)
{
Check.NotNull(source);
Check.NotEmpty(function);
Check.NotEmpty(member);

var queryable = ToQueryable(source);
return queryable.Aggregate(function, member);
}
#endregion Aggregate

#region All
/// <summary>Determines whether all the elements of a sequence satisfy a condition.</summary>
/// <summary>
/// Determines whether all the elements of a sequence satisfy a condition.
/// </summary>
/// <param name="source">A sequence whose elements to test for a condition.</param>
/// <param name="predicate">A function to test each element for a condition.</param>
/// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
Expand All @@ -19,7 +40,9 @@ public static bool All(this JArray source, string predicate, params object?[] ar
return All(source, NewtonsoftJsonParsingConfig.Default, predicate, args);
}

/// <summary>Determines whether all the elements of a sequence satisfy a condition.</summary>
/// <summary>
/// Determines whether all the elements of a sequence satisfy a condition.
/// </summary>
/// <param name="source">A sequence whose elements to test for a condition.</param>
/// <param name="config">The <see cref="NewtonsoftJsonParsingConfig"/>.</param>
/// <param name="predicate">A function to test each element for a condition.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ namespace System.Linq.Dynamic.Core.SystemTextJson;
/// </summary>
public static class SystemTextJsonExtensions
{
#region Aggregate
/// <summary>
/// Dynamically runs an aggregate function on the <see cref="JsonDocument"/>>.
/// </summary>
/// <param name="source">The <see cref="JsonDocument"/>> data source.</param>
/// <param name="function">The name of the function to run. Can be Sum, Average, Min or Max.</param>
/// <param name="member">The name of the property to aggregate over.</param>
/// <returns>The value of the aggregate function run over the specified property.</returns>
public static object Aggregate(this JsonDocument source, string function, string member)
{
Check.NotNull(source);
Check.NotEmpty(function);
Check.NotEmpty(member);

var queryable = ToQueryable(source);
return queryable.Aggregate(function, member);
}
#endregion Aggregate

#region All
/// <summary>
/// Determines whether all the elements of a sequence satisfy a condition.
Expand All @@ -39,7 +58,7 @@ public static bool All(this JsonDocument source, SystemTextJsonParsingConfig con
Check.NotNull(source);
Check.NotNull(config);

var queryable = ToQueryable(source.RootElement, config);
var queryable = ToQueryable(source, config);
return queryable.All(config, predicate, args);
}
#endregion All
Expand All @@ -54,7 +73,7 @@ public static bool Any(this JsonDocument source)
{
Check.NotNull(source);

var queryable = ToQueryable(source.RootElement);
var queryable = ToQueryable(source);
return queryable.Any();
}

Expand All @@ -71,7 +90,7 @@ public static bool Any(this JsonDocument source, SystemTextJsonParsingConfig con
Check.NotNull(source);
Check.NotNull(config);

var queryable = ToQueryable(source.RootElement, config);
var queryable = ToQueryable(source, config);
return queryable.Any(config, predicate, args);
}

Expand All @@ -97,7 +116,7 @@ public static bool Any(this JsonDocument source, LambdaExpression lambda)
{
Check.NotNull(source);

var queryable = ToQueryable(source.RootElement);
var queryable = ToQueryable(source);
return queryable.Any(lambda);
}
#endregion Any
Expand Down Expand Up @@ -129,7 +148,7 @@ public static JsonDocument Select(this JsonDocument source, SystemTextJsonParsin
Check.NotNull(config);
Check.NotNullOrEmpty(selector);

var queryable = ToQueryable(source.RootElement, config);
var queryable = ToQueryable(source, config);
return ToJsonDocumentArray(() => queryable.Select(config, selector, args));
}
#endregion Select
Expand All @@ -151,7 +170,7 @@ public static JsonDocument Where(this JsonDocument source, string predicate, par
/// Filters a sequence of values based on a predicate.
/// </summary>
/// <param name="source">The source <see cref="JsonDocument"/></param>
/// <param name="config">The <see cref="JsonParsingConfig"/>.</param>
/// <param name="config">The <see cref="SystemTextJsonParsingConfig"/>.</param>
/// <param name="predicate">An expression string to test each element for a condition.</param>
/// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
/// <returns>A <see cref="JsonDocument"/> that contains elements from the input sequence that satisfy the condition specified by predicate.</returns>
Expand All @@ -161,7 +180,7 @@ public static JsonDocument Where(this JsonDocument source, SystemTextJsonParsing
Check.NotNull(config);
Check.NotNullOrEmpty(predicate);

var queryable = ToQueryable(source.RootElement, config);
var queryable = ToQueryable(source, config);
return ToJsonDocumentArray(() => queryable.Where(config, predicate, args));
}
#endregion Where
Expand All @@ -179,14 +198,15 @@ private static JsonDocument ToJsonDocumentArray(Func<IQueryable> func)
return JsonDocumentUtils.FromObject(array);
}

private static IQueryable ToQueryable(JsonElement source, SystemTextJsonParsingConfig? config = null)
private static IQueryable ToQueryable(JsonDocument source, SystemTextJsonParsingConfig? config = null)
{
if (source.ValueKind != JsonValueKind.Array)
var array = source.RootElement;
if (array.ValueKind != JsonValueKind.Array)
{
throw new NotSupportedException("The source is not a JSON array.");
}

return JsonDocumentExtensions.ToDynamicJsonClassArray(source, config?.DynamicJsonClassOptions).AsQueryable();
return JsonDocumentExtensions.ToDynamicJsonClassArray(array, config?.DynamicJsonClassOptions).AsQueryable();
}
#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ namespace System.Linq.Dynamic.Core.NewtonsoftJson.Tests;

public class NewtonsoftJsonTests
{
[Fact]
public void Aggregate()
{
// Arrange
var json = @"[
{
""Name"": ""John"",
""Age"": 30
},
{
""Name"": ""Doe"",
""Age"": 25
}
]";

var jArray = JArray.Parse(json);

// Act
var result = jArray.Aggregate("Sum", "Age");

// Assert
result.Should().Be(55);
}

[Fact]
public void All()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
using System.Text.Json;
using FluentAssertions;
using Newtonsoft.Json.Linq;
using Xunit;

namespace System.Linq.Dynamic.Core.SystemTextJson.Tests;

public class NewtonsoftJsonTests
{
[Fact]
public void Aggregate()
{
// Arrange
var json = @"[
{
""Name"": ""John"",
""Age"": 30
},
{
""Name"": ""Doe"",
""Age"": 25
}
]";

var doc = JsonDocument.Parse(json);

// Act
var result = doc.Aggregate("Sum", "Age");

// Assert
result.Should().Be(55);
}

[Fact]
public void All()
{
Expand Down

0 comments on commit 08b5274

Please sign in to comment.