How to generate a unique collection?
This will seem rather basic but somewhere a piece of the logic is alluding me. If I want to create a distinct collection from parsed attributes of a feature query, it seems I would:
- Create a new collection for unique values
- Use a ForEach to move through the attributes collection
- Nest the 'unique' collection ForEach loop inside the attributes collection
- For each attribute,evaluate each unique value - if the attribute is not equal to any unique value, assign to collection with 'AddItem', exit nested loop and move on to next attribute value.
- I've created the necessary values to evaluate the expression and exit ForEach but the logic still picks up duplicate values on each primary ForEach.
I know this is simple and I'm missing the obvious - I just got so used to the 'Exists inCollection' activity in the 4 series and there's far fewer options for collections and tables in W5 that I'm stumped.
I've pulled a small snippet of a much larger workflow and included an attribute collection with duplicates.
Thanks!
-
Hi there,
Is there any reason why you're not using the "Return Distinct Values" option on the Query Layer Activity?
Cheers,
Chris
0 -
That would be ideal but I have an attribute 'Roll_Number' that is 16 digits. It requires being parsed out into four different collections with SQL queries to be performed on each of the collections. Unfortunately the 70k+ records return a lot of duplicates which need to be removed as all queries need to have distinct WHERE statements...this was quite easy with the 'ExistsInCollection' activity in Workflow Essentials.
I'd love to just run a simple function - in any language or script - e.g.
var items = [4,5,4,6,3,4,5,2,23,1,4,4,4]
var uniqueItems = Array.from(new Set(items))
But I can't see any way of getting this done with WF5 without nested ForEach loops....
Thanks,
James
0 -
In Workflow 5 you could do something like this:
=$query1.features.map(f => f.attributes["Roll_Number"]).filter((value, index, self) => self.indexOf(value) === index)The map function converts the list of features to an array containing the attribute values of a field called 'Roll_Number'.
The filter function then filters out duplicate values, as explained here, and returns an array of unique values.
BTW, you do realize that ArcGIS by default returns only 1000 features at a time? So if you have 70k+ records, you'll have to find a way to deal with that.
2 -
Much appreciated Berend! - pardon my inexperience with javascript array manipulation - is this meant to work on a collection of numbers generated from a subset of the feature attribute? For example if the attribute is '165134002047610' we have to parse out '1651', '340', '0204' and '7610', adding them to their respective collections. AS a quick example we may end up with a collection [1651,1651,1550,1550,1650] which we then need to clean up to [1651,1550,1650]. It's on each of these collections we need to return unique value collections for SQL Queries, so we're not working with attribute values from fields directly but parsed collections.
Thanks,
James
0 -
No, in my test I used a Query Layer and then worked with the resulting features.
I missed the part about splitting the number.
Do you need 4 separate unique lists? In that case, I'd use 4 separate Create value activities, and add substring() to each (with parameters (0,4), (4,8), (8,12) and (12,16)).
=$query1.features.map(f => f.attributes["Roll_Number"].substring(0,4)).filter((value, index, self) => self.indexOf(value) === index)If you need just one overall unique list, use concat to merge the four lists first, and then filter. This can even be done in a oneliner, although it becomes a bit harder to read:
=$query1.features.map(f => f.attributes["Roll_Number"].substring(0,4)) .concat($query1.features.map(f => f.attributes["Roll_Number"].substring(4,8))) .concat($query1.features.map(f => f.attributes["Roll_Number"].substring(8,12))) .concat($query1.features.map(f => f.attributes["Roll_Number"].substring(12,16))) .filter((value, index, self) => self.indexOf(value) === index)0 -
Hi Berend, this is greatly appreciated and exactly what i was hoping to find.
I'll give this a try - if it works, drinks are on me!
Cheers!
James
0 -
Fantastic, just what i was looking for. Thank you for the elegance of your solution and all the headaches it will save me. From 653 records it gave me back the correct 3 distinct values of 010,006,060 without issue.
James
0 -
Berend Veldkamp Thank you so much! That was exactly what I needed to get my workflow working. I couldn't use Return Distinct Values on the query because I was pulling the date field off the features and then adding a new field to calculate just the year off them for the picker. Using your text as the input for “Get Form Element Items From Collection” worked for me.
0
Please sign in to leave a comment.
Comments
8 comments