Extension functions for NCalc.
Please submit your requests for new functions in the form of pull requests.
To use:
using PanoramicData.NCalcExtensions;
...
var calculation = "lastIndexOf('abcdefg', 'def')";
var nCalcExpression = new Expression(calculation);
// Add the extension functions
nCalcExpression.EvaluateFunction += NCalcExtensions.NCalcExtensions.Extend;
if (nCalcExpression.HasErrors())
{
throw new FormatException($"Could not evaluate expression: '{calculation}' due to {nCalcExpression.Error}.");
}
return nCalcExpression.Evaluate();
General functions:
- canEvaluate()
- cast()
- convert()
- changeTimeZone()
- dateTime()
- dateTimeAsEpochMs()
- format()
- if()
- in()
- isInfinite()
- isNaN()
- isNull()
- isNullOrEmpty()
- isNullOrWhiteSpace()
- isSet()
- itemAtIndex()
- join()
- jPath()
- length()
- list()
- nullCoalesce()
- regexGroup()
- regexIsMatch()
- switch()
- throw()
- timeSpan()
- toDateTime()
- try()
- typeOf()
String functions:
- capitalize()
- contains()
- endsWith()
- indexOf()
- join()
- lastIndexOf()
- length()
- padLeft()
- parse()
- parseInt() (deprecated - use "parse()" instead)
- replace()
- split()
- startsWith()
- substring()
- toLower()
- toUpper()
- toString()
Supported functions:
Determines whether ALL of the parameters can be evaluated. This can be used, for example, to test whether a parameter is set.
- parameter1, parameter2, ...
- canEvaluate(nonExistent) : false
- canEvaluate(1) : true
Cast an object to another (e.g. float to decimal). The method requires that conversion of value to target type be supported.
- inputObject
- typeString
- cast(0.3, 'System.Decimal')
Change a DateTime's time zone. For a list of supported TimeZone names, see https://docs.microsoft.com/en-us/dotnet/api/system.timezoneinfo.findsystemtimezonebyid?view=netstandard-2.0
- source DateTime
- source TimeZone name
- destination TimeZone name
- changeTimeZone(theDateTime, 'UTC', 'Eastern Standard Time')
- changeTimeZone(theDateTime, 'Eastern Standard Time', 'UTC')
Converts the output of parameter 1 into the result of parameter 2. Can be used to return an empty string instead of the result of parameter 1, which can be useful when the return value is not useful. The result of parameter 1 is available as the variable "value".
- the value to calculate
- destination TimeZone name
- convert(anyFunction(), 'XYZ'): 'XYZ'
- convert(1 + 1, value + 1): 3
Return the DateTime in the specified format as a string, with an optional offset.
- timeZone (only 'UTC' currently supported)
- format
- day offset
- hour offset
- minute offset
- second offset
- dateTime('UTC', 'yyyy-MM-dd HH:mm:ss', -90, 0, 0, 0) : 90 days ago (e.g. '2019-03-14 05:09')
- dateTime('UTC', 'yyyy-MM-dd HH:mm:ss') : now (e.g. '2019-03-14 05:09')
Parses the input DateTime and outputs as milliseconds since the Epoch (1st Jan 1970).
- input date string
- format
- dateTimeAsEpochMs('20190702T000000', 'yyyyMMddTHHmmssK') : 1562025600000
Formats strings and numbers as output strings with the specified format
- object (number or text)
- format: the format to use
- see C# number and date/time formatting
- weekOfMonth is the numeric week of month as would be shown on a calendar with one row per week with weeks starting on a Sunday
- weekOfMonthText is the same as weekOfMonth, but translated: 1: 'first', 2: 'second', 3: 'third', 4: 'forth', 5: 'last'
- weekDayOfMonth is the number of times this weekday has occurred within the month so far, including this one
- weekDayOfMonthText is the same as weekDayOfMonth, but translated: 1: 'first', 2: 'second', 3: 'third', 4: 'forth', 5: 'last'
- timeZone [optional] - see https://docs.microsoft.com/en-us/dotnet/api/system.timezoneinfo.findsystemtimezonebyid?view=netstandard-2.0
- format(1, '00') : '01'
- format(1.0, '00') : '01'
- format('2021-11-29', 'dayOfYear') : '333'
- format('2021-11-01', 'weekOfMonth') : 1
- format('2021-11-01', 'weekOfMonthText') : 'first'
- format('2021-11-28', 'weekOfMonth') : 5
- format('2021-11-28', 'weekOfMonthText') : 'last'
- format('2021-11-28', 'weekDayOfMonth') : 4
- format('2021-11-28', 'weekDayOfMonthText') : 'forth'
- format('01/01/2019', 'yyyy-MM-dd') : '2019-01-01'
- format(theDateTime, 'yyyy-MM-dd HH:mm', 'Eastern Standard Time') [where theDateTime is a .NET DateTime, set to DateTime.Parse("2020-03-13 16:00", CultureInfo.InvariantCulture)] : '2020-03-13 12:00'
Return one of two values, depending on the input function.
- condition
- output if true
- output if false
- if(1 == 1, 'yes', 'no') : 'yes'
- if(1 == 2, 3, 4) : 4
Determines whether a value is in a set of other values.
- list
- item
- in('needle', 'haystack', 'with', 'a', 'needle', 'in', 'it') : true
- in('needle', 'haystack', 'with', 'only', 'hay') : false
Determines the first position of a string within another string. Returns -1 if not present.
- longString
- shortString
- indexOf('#abcabc#', 'abc') : 1
- indexOf('#abcabc#', 'abcd') : -1
Determines whether a value is infinite
- value
- isInfinite(1/0) : true
- isInfinite(0/1) : false
Determines whether a value is not a number.
- value
- isNaN(null) : true
- isNaN(1) : false
Determines whether a value is either:
- null; or
- it's a JObject and it's type is JTokenType.Null.
- value
- isNull(1) : false
- isNull('text') : false
- isNull(bob) : true if bob is null
- isNull(null) : true
Determines whether a value is either:
- null; or
- it's a JObject and it's type is JTokenType.Null or;
- it's a string and it's empty.
- value
- isNullOrEmpty(null) : true
- isNullOrEmpty('') : true
- isNullOrEmpty(' ') : false
- isNullOrEmpty(bob) : true if bob is null or whitespace
- isNullOrEmpty(1) : false
- isNullOrEmpty('text') : false
Determines whether a value is either:
- null; or
- it's a JObject and it's type is JTokenType.Null or;
- it's a string and it's empty or only contains whitespace characters (\r, \n, \t, or ' ').
- value
- isNullOrWhiteSpace(null) : true
- isNullOrWhiteSpace('') : true
- isNullOrWhiteSpace(' ') : true
- isNullOrWhiteSpace(bob) : true if bob is null or whitespace
- isNullOrWhiteSpace(1) : false
- isNullOrWhiteSpace('text') : false
Determines whether a parameter is set:
- parameter name
- isSet('a') : true/false depending on whether a is an available variable
Determines the item at the given index. The first index is 0.
- parameter name
- itemAtIndex(split('a b c', ' '), 1) : 'b'
Joins a list of strings into a single string.
- parameter name
- join(split('a b c', ' '), ', ') : 'a, b, c'
Determines the last position of a string within another string. Returns -1 if not present.
- longString
- shortString
- lastIndexOf('#abcabc#', 'abc') : 4
- lastIndexOf('#abcabc#', 'abcd') : -1
Determines length of a string or IList.
- string or IList
- length('a piece of string') : 17
- length(split('a piece of string', ' ')) : 4
Returns the first parameter that is not null, otherwise: null.
- any number of objects
- nullCoalesce() : null
- nullCoalesce(1, null) : 1
- nullCoalesce(null, 1, 2, 3) : 1
- nullCoalesce(null, null, null) : null
- nullCoalesce(null, null, 'xxx', 3) : 'xxx'
Splits a string on a given character into a list of strings.
- longString
- character
- split('a bc d', ' ') : list('a', 'bc', 'd')
Determines whether a string starts with another string.
- longString
- shortString
- startsWith('abcdefg', 'ab') : true
- startsWith('abcdefg', 'cd') : false
Determines whether a string ends with another string.
- longString
- shortString
- endsWith('abcdefg', 'fg') : true
- endsWith('abcdefg', 'fgh') : false
Selects a single value from a JObject using a JPath expression
- input JObject
- JPath string expression
sourceJObject JSON:
{
"name": "bob",
"numbers": [ 1, 2 ]
"arrayList": [
{ "key": "key1", "value": "value1" },
{ "key": "key2", "value": "value2" }
]
}
- jPath(sourceJObject, 'name') : 'bob'
- jPath(sourceJObject, 'size') : an exception is thrown
- jPath(sourceJObject, 'size', True) : null is returned
- jPath(sourceJObject, 'numbers[0]') : 1
- jPath(sourceJObject, 'arrayList[?(@key==\'key1\')]') : "value1"
Emits a List<object?> and collapses down lists of lists to a single list.
- the parameters
- list('', 1, '0')
- list(null, 1, '0')
- list(list(null, 1, '0'), 1, '0')
Pad the left of a string with a character to a desired string length.
- stringToPad
- desiredStringLength (must be >=1)
- paddingCharacter
- padLeft('', 1, '0') : '0'
- padLeft('12', 5, '0') : '00012'
- padLeft('12345', 5, '0') : '12345'
- padLeft('12345', 3, '0') : '12345'
Returns the conversion of a string to a numeric type. Supported types are:
- sbyte
- byte
- short
- ushort
- int
- uint
- long
- ulong
- double
- float
- decimal
- type (see above)
- text
- parse('int', '1') : 1
Returns an integer version of a string.
- integerAsString
- parseInt('1') : 1
Selects a regex group capture
- input
- regex
- zero-based capture index (default: 0)
- regexGroup('abcdef', '^ab(.+?)f$') : 'cde'
- regexGroup('abcdef', '^ab(.)+f$') : 'c'
- regexGroup('abcdef', '^ab(.)+f$', 1) : 'd'
- regexGroup('abcdef', '^ab(.)+f$', 2) : 'e'
- regexGroup('abcdef', '^ab(.)+f$', 10) : null
Determine whether a string matches a regex
- input
- regex
- regexIsMatch('abcdef', '^ab.+') : true
- regexIsMatch('Zbcdef', '^ab.+') : false
Replace a string with another string
- haystackString
- needleString
- betterNeedleString
- replace('abcdefg', 'cde', 'CDE') : 'abCDEfg'
- replace('abcdefg', 'cde', '') : 'abfg'
Retrieves part of a string. If more characters are requested than available at the end of the string, just the available characters are returned.
- inputString
- startIndex
- length (optional)
- substring('haystack', 3) : 'stack'
- substring('haystack', 0, 3) : 'hay'
- substring('haystack', 3, 100) : 'stack'
- substring('haystack', 0, 100) : 'haystack'
Return one of a number of values, depending on the input function.
- switched value
- a set of pairs: case_n, output_n
- if present, a final value can be used as a default. If the default WOULD have been returned, but no default is present, an exception is thrown.
- switch('yes', 'yes', 1, 'no', 2) : 1
- switch('blah', 'yes', 1, 'no', 2) : throws exception
- switch('blah', 'yes', 1, 'no', 2, 3) : 3
Throws an NCalcExtensionsException. Useful in an if().
- message (optional)
- throw()
- throw('This is a message')
- if(problem, throw('There is a problem'), 5)
Determines the amount of time between two DateTimes.
- startDateTime
- endDateTime
- timeUnit
- timeSpan('2019-01-01 00:01:00', '2019-01-01 00:02:00', 'seconds') : 3600
Converts a string to a UTC DateTime. May take an optional inputTimeZone.
Note that when using numbers as the first input parameter, provide it as a decimal (see examples, below) to avoid hitting an NCalc bug relating to longs being interpreted as floats.
- inputString
- stringFormat
- inputTimeZone (optional) See https://docs.microsoft.com/en-us/dotnet/api/system.timezoneinfo.findsystemtimezonebyid?view=netstandard-2.0
- toDateTime('2019-01-01', 'yyyy-MM-dd') : A date time representing 2019-01-01
- toDateTime('2020-02-29 12:00', 'yyyy-MM-dd HH:mm', 'Eastern Standard Time') : A date time representing 2020-02-29 17:00:00 UTC
- toDateTime('2020-03-13 12:00', 'yyyy-MM-dd HH:mm', 'Eastern Standard Time') : A date time representing 2020-03-13 16:00:00 UTC
- toDateTime(161827200.0, 's', 'UTC') : A date time representing 1975-02-17 00:00:00 UTC
- toDateTime(156816000000.0, 'ms', 'UTC') : A date time representing 1974-12-21 00:00:00 UTC
- toDateTime(156816000000000.0, 'us', 'UTC') : A date time representing 1974-12-21 00:00:00 UTC
Converts a string to lower case.
- string
- toLower('PaNToMIMe') : 'pantomime'
Converts any object to a string
- object
- toString(1) : '1'
Converts a string to upper case.
- string
- toUpper('PaNToMIMe') : 'PANTOMIME'
If a function throws an exception, return an alternate value.
- function to attempt
- result to return if an exception is thrown (nul is returned if this parameter is omitted and an exception is thrown)
- try(1, 'Failed') : 1
- try(throw('Woo')) : null
- try(throw('Woo'), 'Failed') : 'Failed'
- try(throw('Woo'), exception_message) : 'Woo'
- try(throw('Woo'), exception_type) : typeof(PanoramicData.NCalcExtensions.Exceptions.NCalcExtensionsException)
- try(throw('Woo'), exception_typeFullName) : 'PanoramicData.NCalcExtensions.Exceptions.NCalcExtensionsException'
- try(throw('Woo'), exception_typeName) : 'NCalcExtensionsException'
- try(throw('Woo'), exception) : The Exception object thrown by the throw function.
Determines the C# type of the object.
- parameter
- typeOf('text') : 'String'
- typeOf(1) : 'Int32'
- typeOf(1.1) : 'Double'
- typeOf(null) : null
Capitalizes a string.
- string
- capitalize('new year') : 'New Year'
Determines whether one string contains another.
- string searched-in text
- string searched-for text
- contains('haystack containing needle', 'needle') : true
- contains('haystack containing only hay', 'needle') : false
Humanizes the value text.
- value
- timeUnit
- humanize(3600, 'seconds') : '1 hour'