Filter down based on "child" property while count on parent property

Couldn’t figure this out for 7 days myself and w/ community, so may I ask you @Kirill_Leventcov for hints about how to filter among lists of services based on the property ‘token’ (ie: ‘stay’) of a child array for this result:
Click on ‘stay’ => 149 (2 options) | 199 (1 options)

services [  
   categories [   
      {token: stay}, {token: sports},...
           ] 
   price: 149,

   categories [   
      {token: stay}, {token: adventure},...
           ] 
   price: 149,

   categories [   
      {token: stay}, {token: sports},...
           ] 
   price: 199
]

I know well about MAP and GROUP, I just can’t filter down to the ‘token’ while doing the count on the ‘price’ property.

Hi,

You can try this formula assuming each item in the services array is an object:

GROUP(SELECT(services, IS_IN_ARRAY_BY_KEY(item.categories, "token", chosenToken)), item.price, {price: key, numberOfOptions: COUNT(items), options: items})

Where services is your array, and chosenToken is the token the user chose.

You can further map the items object to suit your needs. Consider if the categories needs to be an array of objects or if just an array of texts is sufficient (you can FLATTEN the array if only objects with key “token” exist).

2 Likes

It’s 99% that!
I adapted to my schema and have:
GROUP(SELECT(FLATTEN(MAP(data.ProvidersDBcount, item.services)), IS_IN_ARRAY_BY_KEY(FLATTEN(MAP(FLATTEN(MAP(data.ProvidersDBcount, item.services)), item.category)), "token", params.categParam)), item.price, {price: key + " ("+COUNT(items)+")"})
But it counts items (price 279) it should not. The formula gets tricked by this data schema where selected token ‘stay’ exists only in second array ‘category’.


Which formula is to be added to my filter?

Update: I suspect that FLATTEN “merges” these services lists and so 279 is now associated with the tokens this price should not be with. How do I overcome this?

Hi,

Apologies, FLATTEN wasn’t the right formula function to use - in this case, it’d be easiest to MAP the categories property with PLUCK(item.categories, "token"). Then, you would use the IS_IN_ARRAY instead of IS_IN_ARRAY_BY_KEY as the SELECT filter.
Try opening the app (preview) and seeing if the formula works in action there. For me, the example results in the formula editor were showing some odd results at times, but everything worked perfectly fine in the app itself.

1 Like

Thanks tons.
This is the formula you’re suggesting:

GROUP(SELECT(FLATTEN(MAP(data.ProvidersDBcount, item.services)), IS_IN_ARRAY(PLUCK(item.category, “token”), params.categParam)), item.price, {price: key + " (“+COUNT(items)+”)"})

Only thing “odd” is the time it takes to display the result when page params value includes %20. Is this normal for url parameter?

Page5?currParam=USD&categParam=For%20her

Do you mind explaining in simple English how IS_IN_ARRAY works inside the SELECT formula… or how SELECT reads/understand IS IN ARRAY?

The FLATTEN is unnecessary unless you have a list of lists in your schema, I would not use it in this case. Also, if you want to preserve the categories being a list of objects instead of a list of strings, you don’t really need to PLUCK either - that’s a consideration for changing the entire schema. My initial proposed formula is still the one I suggest (with the added text formatting).

The SELECT formula takes two parameters: the array, and something that yields a true/false value to determine if this part of the original array should be included in the result. In this case, we want to determine if any of the items in the category property has the chosen token.

Let’s look at what’s going on with the SELECT and IS_IN_ARRAY(_BY_KEY) formulas step by step:

  1. SELECT looks at the next (or first) item in the services array.
  2. IS_IN_ARRAY_BY_KEY is evaluated for this item. In our case, it looks at the item.categories and sees if any of the tokens is equal to chosenToken.
  3. a) If any token that matches chosenToken is found, the IS_IN_ARRAY_BY_KEY immediately exits and yields true.
    b) If there’s no match, the IS_IN_ARRAY_BY_KEY yields false.
  4. If the result of step 3 is true, the entire item is added to the result of the SELECT formula function. If it’s false, the item is ignored. In any case, we go back to step one until we’ve gone through the entire services array.

I hope this clear things up. I’m not sure about the URL parameter affecting the time it takes to display results, that shouldn’t be happening if everything is implemented properly.

1 Like

Thanks for the detailed explanation about SELECT.

This formula works as intended. I was just sharing to the readers how it looked after your PLUCK fix.

But I do have a list of list: a list of Documents (see my firebase screenshot), each containing a list of services.

And I am too far in the development steps to change the schema now. Tokens in a list of objects make sense for my current logic flows.

We’re all good now, thanks for the solution.