Jyro 0.9.0

Jyro’s execution engine has been stable for a while now, and we have been successfully running production workloads against Jyro with no issues so far. As our confidence in testing and using Jyro in real-world applications increases we turn our attention to squeezing even more performance for more advanced use-cases that we feel should be covered in preparation for 1.0 release.

Jyro 0.9.0 comes with several such advanced use-case functions. Jyro now includes four functions for pattern matching using regular expressions.

RegexMatch returns the first substring that matches a pattern, or null if no match exists. The string return type allows direct chaining with other string functions such as Upper() or Length().

RegexMatchAll returns all matching substrings as an array. When no matches are found, it returns an empty array. Results can be passed directly to array functions like Filter(), First(), or Join().

RegexTest returns a boolean indicating whether a pattern matches anywhere in the text. Use this function when you need to check for pattern existence without extracting the matched content.

RegexMatchDetail returns an object containing the matched string, its zero-based index position, and an array of captured groups. This function is intended for cases where capture group values or match position are required. Returns null when no match is found.

All four functions throw a runtime exception if the pattern is not a valid regular expression. Patterns use .NET regular expression syntax, with the constraint that Jyro strings require character class alternatives for common shortcuts ([0-9] instead of \d, [a-zA-Z0-9_] instead of \w).

Rounding out this release are seven new functions that simplify common array and object operations. These functions replace verbose loop-based patterns with expressive, single-line alternatives.

Boolean Array Checks

Any and All provide efficient boolean checks across arrays without requiring intermediate filtering steps.

Any returns true if at least one element matches a field comparison, short-circuiting on the first match. This replaces the common pattern Length(Filter(array, field, op, value)) > 0 with a more readable and efficient alternative. Returns false for empty arrays.

All returns true only when every element satisfies the condition, short-circuiting on the first non-match. Empty arrays return true following the mathematical convention of vacuous truth—a consideration worth noting when validating user input.

Both functions accept the same four-parameter signature as Filter and CountIf: an array, a field name supporting dot-notation paths, a comparison operator, and a value. The consistency across these functions means learning one teaches you all.

Element Lookup

Find returns the first element matching a condition, or null if no match exists. Where First(Filter(...)) processes the entire array before returning, Find stops at the first match. For large arrays or expensive comparisons, this distinction matters.

Field Extraction

Select extracts a single field from each object in an array, returning the values as a new array. Combined with aggregation functions, this enables patterns like Sum(Select(orders, "amount")) to replace manual accumulation loops. Non-object elements become null in the result.

SelectMany performs the same extraction but flattens the result when the field contains arrays. Extracting a "tags" field from products where each product has multiple tags returns a single flat array of all tags rather than an array of arrays.

Project extracts multiple fields from each object, returning an array of new objects containing only the specified properties. This function simplifies API response shaping and report generation where only a subset of fields is needed. Field names support dot-notation for nested property extraction.

Object Combination

Merge combines multiple objects into a single new object, with later arguments overriding earlier ones for conflicting keys. The function accepts any number of arguments, silently skipping non-objects. Common uses include applying user preferences over defaults or assembling dashboard summaries from multiple data sources.

This is a shallow merge—nested objects are replaced entirely rather than recursively merged. For deep merging requirements, explicit handling of nested structures remains necessary.

Previous
Previous

So, we re-wrote Jyro

Next
Next

Jyro 0.8.0