diff --git a/src/WorkflowActivityLibrary/Common/EventIdentifier.cs b/src/WorkflowActivityLibrary/Common/EventIdentifier.cs
index 8157560..de36940 100644
--- a/src/WorkflowActivityLibrary/Common/EventIdentifier.cs
+++ b/src/WorkflowActivityLibrary/Common/EventIdentifier.cs
@@ -1258,6 +1258,11 @@ namespace MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.Common
///
public const int ExpressionFunctionMod = 11686;
+ ///
+ /// The event identifier for ExpressionFunction IndexByValue events
+ ///
+ public const int ExpressionFunctionIndexByValue = 11687;
+
///
/// The event identifier for LookupEvaluator Constructor events
///
@@ -3133,6 +3138,16 @@ namespace MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.Common
///
public const int ExpressionFunctionModInvalidSecondFunctionParameterTypeError = 41686;
+ ///
+ /// The event identifier for ExpressionFunction ValueByIndex events
+ ///
+ public const int ExpressionFunctionIndexByValueInvalidFunctionParameterCountError = 41687;
+
+ ///
+ /// The event identifier for ExpressionFunction IndexByValue events
+ ///
+ public const int ExpressionFunctionIndexByValueNullFunctionParameterError = 41645;
+
///
/// The event identifier for LookupEvaluator Constructor events
///
diff --git a/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs b/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs
index 50a6d2f..884993e 100644
--- a/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs
+++ b/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs
@@ -222,6 +222,9 @@ namespace MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.Common
case "IIF":
return this.IIF();
+ case "INDEXBYVALUE":
+ return this.IndexByValue();
+
case "INSERTVALUES":
return this.InsertValues();
@@ -2676,6 +2679,70 @@ namespace MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.Common
}
}
+ ///
+ /// This function is used to retrieve the index for a specific value within the input list.
+ /// Function Syntax: IndexByValue(values:[list or object], value:object)
+ ///
+ /// The index of the specified value in the input list. If the value is not found in the list, null is returned.
+ private object IndexByValue()
+ {
+ Logger.Instance.WriteMethodEntry(EventIdentifier.ExpressionFunctionIndexByValue, "Evaluation Mode: '{0}'.", this.mode);
+
+ try
+ {
+ if (this.parameters.Count != 2)
+ {
+ throw Logger.Instance.ReportError(EventIdentifier.ExpressionFunctionIndexByValueInvalidFunctionParameterCountError, new InvalidFunctionFormatException(Messages.ExpressionFunction_InvalidFunctionParameterCountError, this.function, 2, this.parameters.Count));
+ }
+
+ // default value if no results are found
+ int result = -1;
+
+ if (this.mode != EvaluationMode.Parse)
+ {
+ if (this.parameters[0] != null && this.parameters[1] != null)
+ {
+ Type paramType = this.parameters[0].GetType();
+ if (paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(List<>))
+ {
+ Logger.Instance.WriteVerbose(EventIdentifier.ExpressionFunctionIndexByValue, "IndexByValue('{0}', '{1}') First parameter is a list. Enumerating list items.", this.parameters[0], this.parameters[1]);
+
+ int index = 0;
+ foreach (object item in (IEnumerable)this.parameters[0])
+ {
+ if (item is string && this.parameters[1] is string)
+ {
+ if (item.ToString().Equals(this.parameters[1].ToString(), StringComparison.InvariantCultureIgnoreCase))
+ {
+ Logger.Instance.WriteVerbose(EventIdentifier.ExpressionFunctionIndexByValue, "IndexByValue('{0}', '{1}') Matched string item '{2}' to second param '{3}'. Result: {4}.", this.parameters[0], this.parameters[1], item.ToString(), this.parameters[1].ToString(), index);
+ result = index;
+ break;
+ }
+ }
+ else if (item.Equals(this.parameters[1]))
+ {
+ Logger.Instance.WriteVerbose(EventIdentifier.ExpressionFunctionIndexByValue, "IndexByValue('{0}', '{1}') Matched object item '{2}' to second param '{3}'. Result: {4}.", this.parameters[0], this.parameters[1], item.ToString(), this.parameters[1].ToString(), index);
+ result = index;
+ break;
+ }
+
+ index += 1;
+ }
+ }
+
+ }
+
+ Logger.Instance.WriteVerbose(EventIdentifier.ExpressionFunctionIndexByValue, "IndexByValue('{0}', '{1}') returned '{2}'.", this.parameters[0], this.parameters[1], result);
+ }
+
+ return result;
+ }
+ finally
+ {
+ Logger.Instance.WriteMethodExit(EventIdentifier.ExpressionFunctionIndexByValue, "Evaluation Mode: '{0}'.", this.mode);
+ }
+ }
+
///
/// This function is used to create a new InsertedValues collection which contains all values from the specified list.
/// This InsertedValues collection will be used by the activity so that it can generate update request parameters accordingly.