Collection Operations


Userlevel 4
Badge +7

After creating this blog post Collection Operation - Get , i thought it would be good to look at the other Collection Operations in some detail too.

As stated in the article above, the Collection Operation action allows you to interact with a Collection Variable. This can be useful in many situations.

 

Add

This method allows you to add to a value at a specific index within a collection

Original Collection - Audi; BMW; Volkswagen

Value to add - Mercedes

Index - 2

Resulting Collection - Audi; BMW; Mercedes, Volkswagen

 

Remove

This method allows you to remove a value from a specific index within a collection

Original Collection - Audi; BMW; Volkswagen

Value to Remove - BMW

Index - 1

Resulting Collection - Audi; Volkswagen

 

Count

This method allows you to count the number of items in a collection

Original Collection - Audi; BMW; Volkswagen

Result - 3

 

Get

This method allows you to get a value from a specific index within a collection

Original Collection - Audi; BMW; Volkswagen

Index - 1

Result - BMW

 

Exists

This method returns the index of a value within a collection if the value is in the collection, returns null if the value doesn't exist

Original Collection - Audi; BMW; Volkswagen

Value - Audi

Result - 0

Original Collection - Audi; BMW; Volkswagen

Value - Mercedes

Result -

 

Sort

This method sorts the items in a collection

Original Collection - Audi; BMW; Volkswagen

Order - Ascending

Result - Audi; BMW; Volkswagen

Order - Descending

Result - Volkswagen; BMW; Audi

 

Pop

This method returns the last value in a collection

Original Collection - Audi; BMW; Volkswagen

Result - Volkswagen

Resulting Collection - Audi; BMW

 

Join

This method joins all the values in a collection with a specified delimiter and stores in a variable (not a collection variable)

Original Collection - Audi; BMW; Volkswagen

Delimiter - ,

Result - Audi, BMW, Volkswagen

 

Clear

This method clears all items in a collection

Original Collection - Audi; BMW; Volkswagen

Result -

 

Remove Duplicates

This method allows you to remove duplicate items in a collection

Original Collection - Audi; BMW; BMW; Volkswagen

Resulting Collection - Audi; BMW; Volkswagen

 

Remove by Value

This method allows you to remove items from a collection if the value exists. If the value doesn't exist the original collection is returned

Original Collection - Audi; BMW; Volkswagen

Value - BMW

Resulting Collection - Audi; Volkswagen

Original Collection - Audi; BMW; Volkswagen

Value - Mercedes

Resulting Collection - Audi; BMW; Volkswagen

 

Have fun with collections!!!


27 replies

Userlevel 6
Badge +15

This is super handy, thank you for writing this! You made this really easy to understand.

This is a great overview, thank you Paul.  Out of the "get" and "pop" operations, which would you say is more efficient?

Userlevel 4
Badge +7

Pop is great to get the last value in a collection. Get is for a specific index in a collection so i use both depending on the circumstances to be honest

Badge +8

Under the "Remove Duplicates" explanation there is a missing word which could lead to confusion.

"This method allows you to duplicate items in a collection" should read

"This method allows you to remove duplicate items in a collection"

Userlevel 4
Badge +7

Thanks

Have updated

Very helpful, especially to me as a newcomer to Nintex Workflow for SharePoint.

Thanks Paul Crawford‌!!  collection operation #

Userlevel 4
Badge +7

Glad I could help. Let me know know if you need more help

Get Outlook for iOS<https://aka.ms/o0ukef>

Userlevel 6
Badge +13

Hi

Just perusing the help info on the Exists operation and notice that the Nintex explanation suggests that this operation returns a Yes/No rather than the Index like you have suggested.

Currently I'm struggling to return either. The return value field allows me to select collections, nums and bools so not entirely sure what to run with here. But as it is, I'm struggling to get a match.

Basically, I'm building a collection of values selected in a form (colSelectedItems), then building a collection of values from items in a list (colAllItems). The workflow then loops through colAllItems and on each loop uses the Exists collection operation to check whether there's a match in colSelectedItems.

My history looks a little like this.

The first higlighted line is the contents of colSelectedItems and the second highlighted line is the variable from my for each loop of the colAllItems collections.

The only thing I can think of is the ";" but this is just there a delimeter surely, it shouldn't be considered in the Exists operation should it?

I've the bool and returned nothing. I was going to try the num but the problem here is that I need to evaluate whether it was found or not, and as you can't create a num variable without giving it a default value then it will always have a value, and obviously that value could be 0 as it's default value or 0 if it's the first item in the index, so not much use to me to evaulate an "exists/not exists" argument. So I've tried storing the result in a collection and then iterating through that collection to break it out into a variable (as I know there will only ever be one match, but that returns emtpy as can be seen in the screenshot above for every line where I've put "Current Mechanic Found".

Any suggestions?

Userlevel 5
Badge +14

A Number (not integer) value should work just fine being that it should return a value of -1 if the value you're searching for inside of the Collection cannot be found. 

Ex. 

I have a collection variable called someCollection with three entries 
"Audi, BMW, Volkswagen" 

And I have (4) Number Variables, as shown: 

Running the "Exists" Collection Operation the values, "Audi", "BMW", "Volkswagen", and "Ford" 

Results in the following output: 

Setting a condition to know if the value exists is a matter of using a Run If, or , Condition Action and checking whether or not the resulting index variable is lesser than 0. 

If it is, the item doesn't exist. 


Userlevel 6
Badge +13

Thanks, I wasn't aware it returned -1 if the value didn't exist. This makes life a lot easier.

Now I just need to figure out why my value is not being found.

Userlevel 5
Badge +14

Before iteration, have the entire collection sent to you in an email and physically see which values exist. 

It's a lot easier to Ctrl+F to find a needle in a haystack. 

 

Good luck. 

Userlevel 6
Badge +13

Thanks. I was writing to the history list and eventually, with a bit of help, found the culprit. A naughty space preceding a value which was created by another workflow, so was able to tug the thread and correct that error.

Badge +5

Paul, this is a very useful article with lots of details. Thanks. Quick question - has anyone documented the behavior of Collection variables when they're used with consecutive Queries? For example, if I query a list and store the results in colResults, then Query another list and store the results in the same collection variable - does it append or overwrite?

TIA,

Gerard

Userlevel 5
Badge +14

It will be overwritten. 

The Collection is empty before the first query. 

The first query overwrites the emptiness. 

The second query overwrites the first query. 

That being said, you can append to a collection variable by using the Collection Operation action, but not in a 'bulk' or at once kinda way. So it's probably good to just use another variable. 

Badge +6

Paul Crawford‌, this is a very helpful post with definitions and then examples for each collection operation. Do you or anyone else out there reading these know what might be an O365 replacement for Collection Operation "Pop"? Is it Remove Last Item from Collection?

Userlevel 4
Badge +7

Hi Jeremy.

Pop is exactly that so I would assume so. I don't use o365 so I can't say for certain but it sounds like it is

Let me know how you get on.

Paul

Get Outlook for iOS<https://aka.ms/o0ukef>

Badge +6

Hi Paul.

I found that "Remove Last Item from Collection" works as the replacement for Pop in the O365 version. A few extra steps as compared to the On-Prem version of Nintex, but was able to find a solution for this and get it to work.

Quick Question - Can you add a collection to a collection or only items?

which would require looping through one collection to add values to the other.

- On Prem

Badge +5

William, the only method I'm aware of to add to a collection is the method you described - looping through one collection to add values to the other. As an alternative you can also use a SharePoint list to store collected values of varying type.

Badge +5

You may like to mention that if you output a collection variable to the history list, it gets rendered as a ';' delimited list (up to 255 characters anyway)

Very handy for debugging

Userlevel 2
Badge +11

Another question: When going through a collection using for-each, removing an item by index seems to confuse the for-each loop. Example I've 3 items in the collection. When I delete the 2nd, it never gets to the 3rd one. What would be the better way to remove items while loopng through a collection? For now I tend to copy valid items into a new collection.

Badge +5

The problem is that after you delete item 2, item 3 becomes the new item 2.

One way to get around this is to not use the for-each, but to manually loop from the (CountOfItems - 1) to 0 (ie decrementing the counter within the loop) - this means that any changes only affect items after the one you are currently processing.

Userlevel 5
Badge +14

That would also be the expected behavior in most programming languages as well (as they usually do not create a duplicate of the array / collection being iterated). 

However, there are 2 primary ways I would sidestep this issue.

  1. Run a Collection Operation on the Collection to get a Count, subtract 1 from that total, and then use that value to deincrement (always go largest to smallest otherwise you run into the same problem) using a normal Loop action which contains another Collection Operation that uses the current value of that var as the Index to Get from. 

  2. If you just want to use a For Each loop because it's less hassle, and the logic to figure out what should or shouldn't be deleted from the initial collection is inside of that loop, just create an additional Collection Variable that you can Add those values / indexes to that need to be flagged for deletion. 

    • Variation: I have a case where I have a Repeating Section that generates a Unique ID per Row, and a List of Items where each Item contains a Unique ID from the Repeating Section Row that is tied to it. 

      When determining if I need to Update, Create, or Delete a List Item, I create a Collection for both the Unique IDs on the List, and the Unique IDs of the Repeating Section

      I only loop through the Repeating Section IDs, but at the start of the loop use the Collection Operation Action of 'Exists' to see if the current value is present in the List Collection of Unique IDs.

      • If the Value is equal to or greater than 0, Then the item exists, I can remove it from the List Unique IDs Collection and go down the Update Path. 

      • If the Value is lesser than 0, Then the item doesn't exist and I can go down the Make New Item Path. 

Once I have finished, ANYTHING left in the List Unique ID Collection is something that can be Deleted because the ID was no longer found in the Repeating Section, meaning someone has removed it!

Clear as mud, right? 

I hope this helps. 

Userlevel 2
Badge +11

N M‌, graham,

Thank you for your replies and confirming the behavior. The regular Loop is not a real option because if  I recall correctly it include a Pause every cycle. Although it's a small collection, it still would unnecessarily slow down my workflow. So I'll go for adding the valid items into another collection.

NB: as for removing in a collection in e.g. C# I would expect the foreach and the collection's .Remove()  to handle this properly so the foreach can continue.... but it's been some time since last I worked with collections in C# or JS.

Badge +5

Jean-Pierre

See this article nintex-workflow-fast-loops in which I describe how to use a collection to iterate a loop quickly; this could be used as the basis for the above method.

Reply