In Power Automate, we parse a lot of strings and collections. Sometimes it's essential to know whether something exists inside another collection. The "contains" function does exactly that.
For example, if you want to walk through a list of people and build a list of unique names, you would:
- Define an array variable.
- For each element, check whether it's already in the array.
- If it isn't, add it.
It's a simple example, but it would be a lot harder without the "contains" function.
So let's see how to use it.
Usage
It follows a simple pattern.
- Collection (a string, an array, or a dictionary)
- Value to search for
Find a substring inside a string
The most common use is checking whether a string contains a piece of text.
contains('hello world','world')
will return
true
The match is substring-based, so partial matches work fine.
Find a value inside an array
Arrays work the same way, but the value you pass needs to be one of the array elements.
createArray('1','2','3')
contains(variables('TEST_ARRAY'),'2')
will return
true
It makes sense, since '2' exists somewhere in the collection. But what happens if we pass the integer 2 instead of the string '2'?
createArray('1','2','3')
contains(variables('TEST_ARRAY'),2)
will return
false
Piotr flagged in the comments that an earlier version of this article showed true here, which was incorrect. The function does not coerce types, so the integer 2 is not the same as the string '2'.
Power Automate does not auto-convert between types, so the comparison fails. We'll see the same behavior with booleans below.
Speaking of comparisons, let's try with spaces and see what we get.
createArray('Manuel','T','Gomes')
contains(variables('STRING_ARRAY'),' T ')
will return
false
The string needs to match the absolute value. So let's try the opposite way.
createArray('Manuel',' T ', 'Gomes')
contains(variables('ARRAY_WITH_SPACES'),'T')
will return
false
Again, the string needs to match the exact same characters.
Let's try with boolean values:
createArray(true,false)
contains(variables('BOOLEAN_ARRAY'),true)
will return
true
createArray(true,false)
contains(variables('BOOLEAN_ARRAY'),false)
will return
true
How about this?
createArray(true,false)
contains(variables('BOOLEAN_ARRAY'),'true')
will return
false
Why? The datatypes are different, so the comparison fails. This is the same behavior we saw with the integer example: no type coercion.
Finally, let's test another collection.
createArray('Manuel','T','Gomes')
contains(variables('STRING_ARRAY'),'["Manuel","T","Gomes"]')
will return
false
Although they have the same structure, Power Automate treats the second parameter as a string, not an array. There is a flip side, though: when the left-hand side is a string (even one that looks like a JSON array), "contains" does substring matching on the text.
contains('["Manuel","T","Gomes"]','Manuel')
will return
true
This works because the text "Manuel" literally appears inside the string, not because Power Automate parsed it as an array. The same expression with 'Manu' would also return true. So you can sometimes swap a createArray call for a JSON string, but treat it as a substring search, not as real array membership.
Find a key inside a dictionary
When the collection is a dictionary (an object), "contains" checks for a key, not a value.
contains(json('{"name":"Manuel","city":"Lisbon"}'),'name')
will return
true
contains(json('{"name":"Manuel","city":"Lisbon"}'),'Manuel')
will return
false
This is handy when you want to check whether an optional property is present in a JSON payload before reading it.
Edge Cases
"contains" is case-sensitive
This is the gotcha that catches almost everyone the first time. The function does not normalize case.
contains('Manuel T Gomes','manuel') returns false, while contains('Manuel T Gomes','Manuel') returns true.
The standard workaround is to lowercase both sides before comparing.
contains(toLower(variables('NAME')),toLower('manuel'))
That way the comparison is case-insensitive without any extra logic.
Types must match exactly
As we saw above, integer 2 does not match string '2', and boolean true does not match string 'true'. If your data could come in as a different type than you expect, convert it explicitly with the string, int, or bool function before calling "contains".
Watch out for null inputs
If the collection parameter is null (for example, a SharePoint field that was never filled in), "contains" throws a runtime error instead of returning false. To stay safe, fall back to an empty value with coalesce.
contains(coalesce(variables('NAME'), ''), 'manuel')
The same idea works for arrays: coalesce(variables('LIST'), createArray()).
Limitations
There are a few things to keep in mind.
Expression size limit
Power Automate caps expressions at 8,192 characters. If your expression grows even close to 1000 characters, break it up using Compose actions. Long inline expressions are hard to debug anyway.
You can't search arrays inside arrays
"contains" will not match a sub-array against a parent array, and it won't match a JSON-encoded array string against a real array either, as we saw earlier.
You can't search objects inside arrays
If you have an array of objects and you want to know whether a specific object is in there, "contains" won't help. You'll need a Filter Array action or an "Apply to each" loop with the right comparison.
Case sensitivity
Already covered above, but worth repeating: "contains" is case-sensitive. If that's not what you want, lowercase both sides.
Recommendations
Here are some things to keep in mind.
Use "debug" Compose actions
Since the comparison returns true or false, it can be tricky to understand how a complex expression is being evaluated. I recommend using Compose actions to surface the values that go "in" to the function. This way, when the result doesn't make sense, you can see the parameters and figure out why.
Don't feed a "contains" result back into another "contains"
"contains" returns a boolean, not a collection, so passing its output as the collection parameter of another "contains" will fail. You can absolutely use "contains" inside other expressions like "if", "and", or "or", that's fine and very common. The thing to avoid is treating the boolean result as if it were a list.
Final Thoughts
The "contains" function is a small but mighty helper when you need to check membership inside strings, arrays, or dictionaries. Just remember that it cares about exact matches and data types, and that it is case-sensitive. A quick "toLower" call or a debug Compose action will save you a lot of head-scratching when something doesn't behave the way you expect.
Sources
Microsoft's contains Function Reference
Back to the Power Automate Function Reference.
Photo by Michael Dziedzic on Unsplash
Hi, can the contains function be used in the below scenario? I tried different various and all return false... [ { "id":1, "nombre":"Kate" }, { "id":2, "nombre":"Ana" } ]
Hi Liz, Searching in JSON arrays is hard with the "Compose" function, but you can use the Filter Array. I'll write an article in the future, but you can use the Filter Array action with an equals like this: <img src="https://manueltgomes.com/wp-content/uploads/2022/12/Screenshot-2022-12-01-at-10.16.06.png" alt="" /> You'll get the following: <img src="https://manueltgomes.com/wp-content/uploads/2022/12/Screenshot-2022-12-01-at-10.16.00.png" alt="" /> Can you please try and let me know if it works?
Hi Manuel, I receive false when I use contains with int number and the TEST_ARRAY stores numbers as strings '1','2','3'.