Skip to main content
November 2, 2021
Question

Is there any way to make a kind of notWhereContains from a list ?

  • November 2, 2021
  • 14 replies
  • 1 view

Hi,

If I need to get the vehicles Data where ID in {1,2,3}, I can do this :

index(
	ri!vehicles,
	wherecontains(
	    {1, 2, 3}, 
	    ri!vehicles.id
	)
)

But is there any way to do the same thing with a negation (a kind of notWhereContains) ? I mean I need to get the vehicles data where ID not in {1, 2, 3}.

Of course, I can then use a foreach to get the correct data, or create an exclusion list items, to apply the whereContains on the latter,

but is there any other way to do it with a single simple instruction ?

14 replies

stewart.burchell
November 2, 2021

Can you not create a list using wherecontains() and then use the set function 'difference' to get those items NOT in the list you just generated?

November 2, 2021

Yes of course... when I was talking about "create an exclusion list items" it is exactly the difference I was thinking about.

stefanhelzle0001
Brainy
November 2, 2021

You can also simply wrap it into a not().

A foreach() is not directly meant to be used for filtering as it creates a list with an output item for each input item. This is heavily discussed here in case you want to explore that.

November 2, 2021

Stefan, can you modify my example with a "not()" please ? I'm not sure to see what your mean

stefanhelzle0001
Brainy
November 2, 2021

I think I was reading your code too fast. Does not make any sense ...

mikes0011
Brainy
November 2, 2021

whereContains() essentially does this:

a!forEach(
  items: ri!array,
  expression: if(
    contains(
      ri!values,
      fv!item
    ),
    fv!index,
    {}
  )
)

Therefore you could create your own "where not contains" rule by flipping the internal logic of this:

a!forEach(
  items: ri!array,
  expression: if(
    contains(
      ri!values,
      fv!item
    ),
    {},
    fv!index
  )
)

The Expression Guru
November 2, 2021

Thank you Mike, very interesting.

Initially a was using Foreach to make the "where not contain", then, I've tested Difference too.

In any case an internal foreach is used, so it does reply to my question...
and I have some choice now :-)

mikes0011
Brainy
November 2, 2021

My overall suggestion is that if you find yourself using such functionality often, encapsulate it in an expression rule where you decide what the input(s) and output are, then come up with the expression code afterwards (in which you could try different things or potentially change it in the future to something more efficient as new functions become available).  I have lots of "quasi black-box" expression helper rules like this set up in my systems, and it takes a lot of the guesswork out of things.

The Expression Guru
November 2, 2021

Replacing the index function with fn!remove also helps achieve your use-case.

a!localVariables(
  local!vehicles: {
    a!map(id: 1, vehicle: "A"),
    a!map(id: 2, vehicle: "B"),
    a!map(id: 3, vehicle: "C"),
    a!map(id: 4, vehicle: "D"),
    a!map(id: 5, vehicle: "E")
  },
  remove(
    local!vehicles,
    wherecontains({ 1, 3, 5 }, local!vehicles.id)
  )
)

November 2, 2021

Thank you Siddharth, interesting... I did not think about such a way...